OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Mar 29, 2024 12:14 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Kernel ELF Header - Not Present & Dynamic Linking for Module
PostPosted: Tue Oct 17, 2017 9:45 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
Hi OSDevers,

I am developing a OS kernel in the ELF format. I am implementing modules and required information on the kernel's symbol table to link up with the kernel modules. Understanding the ELF documentation is quite difficult for me, and I think it is a little incomplete about some things (maybe I am really wrong about this).

1. My kernel is loaded at 0xC0100000 (virtual address) and I check for the ELF magic numbers there and they aren't there. Does GRUB not write the ELF header there? Do I have to use the MULTIBOOT_ELF_SECTION type in Multiboot2.h instead of using the elf header for getting information on sections (no other information is there). Because then, I will have to write code specially for the 'core-kernel-binary'.

2. I am confused about the GOT (Global Offset Table) and PLT (Procedure Linkage Table). I have created a simple module - name KTERM. I am using GCC with -l MainKernel to (dynamically) link with the kernel. I found a relocation table using readelf. How should I locate and use the GOT and PLT to finish the linking of modules?

3. ELF Symbols - ELF32_SYMBOL contains the field 'Value' (see ELF documentation). It is the value of the symbol. Why is that needed and does it need to be bothered by my loader?

4. How do I locate the relocation table. readelf shows no DT_RELA or related tags in dynamic section. Do I use the section name ".rel.dyn" or type SHT_RELA (section type) to locate the relocation section?

5. How do I do relocation? I get what relocations are and what the entries are. I am confused by the specs in what to 'calculate'.

Thank You,
Shukant Pal


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Tue Oct 17, 2017 11:23 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
There are basically two ways to load ELF code at runtime:
  • Compile the code to an object file and perform the final link during runtime.
  • Compile the code to a shared object, perform dynamic linking at runtime.

The advantages of the first approach relative to the second are:
  • The first approach might be a bit easier to understand as there is no GOT and PLT.
The disadvantages are:
  • The code and data segments cannot be shared (this won't be a problem for the kernel).
  • Requires write access to the code segment, which might have security implications.

You're considering the second approach. It might make sense to also take a look at the first one.

Regarding your questions:

SukantPal wrote:
1. My kernel is loaded at 0xC0100000 (virtual address) and I check for the ELF magic numbers there and they aren't there. Does GRUB not write the ELF header there? Do I have to use the MULTIBOOT_ELF_SECTION type in Multiboot2.h instead of using the elf header for getting information on sections (no other information is there). Because then, I will have to write code specially for the 'core-kernel-binary'.

The ELF standard only requires GRUB to load the segments that are defined by PHDRs (see readelf -l). Those segments are enough to perform dynamic linking, so you don't need to look at ELF sections. Dynamic linking information is stored in the PT_DYNAMIC segment. In particular, the public symbols are accessible through the DT_SYMTAB entry. Notice the difference between sections (relevant during compile-time linking) and segments (relevant during runtime). If you need to access your kernel's PHDRs during runtime, make sure it has a PT_PHDR segment.

SukantPal wrote:
2. I am confused about the GOT (Global Offset Table) and PLT (Procedure Linkage Table). I have created a simple module - name KTERM. I am using GCC with -l MainKernel to (dynamically) link with the kernel. I found a relocation table using readelf. How should I locate and use the GOT and PLT to finish the linking of modules?

You mostly do not need to care about GOT and PLT. The only thing you need to care about is putting your lazy binding stub information into GOT slots 1 and 2. If you don't know what lazy binding is, google it. The GOT can be found through the (extremely stupidly named) DT_PLTGOT entry.

SukantPal wrote:
3. ELF Symbols - ELF32_SYMBOL contains the field 'Value' (see ELF documentation). It is the value of the symbol. Why is that needed and does it need to be bothered by my loader?

That is generally the virtual address/offset of the symbol. It's interpretation depends on the file type.

SukantPal wrote:
4. How do I locate the relocation table. readelf shows no DT_RELA or related tags in dynamic section. Do I use the section name ".rel.dyn" or type SHT_RELA (section type) to locate the relocation section?

Use DT_RELA and DT_REL. If they not present there is either no relocation necessary, or you're compiling your files incorrectly.

SukantPal wrote:
5. How do I do relocation? I get what relocations are and what the entries are. I am confused by the specs in what to 'calculate'.

That question is quite broad. What you have to calculate depends on the relocation type. If it helps: In my code, the calculation looks like this: Click me. Note that R_X86_64_JUMP_SLOT entries have to be initialized even if you use lazy binding.

If you need material on linking I suggest checking out Ian Lance Taylor's blog series.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Wed Oct 18, 2017 5:14 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
Hi Korona,

1. I get what you are saying about the program headers & segments. I number of questions arise on what you have given -
i) How do I locate where these segments are? I have only used SECTIONS in the linker script. I am really unknown to program segments and have heard about them after
starting to load modules. How will I access data in the PT_DYNAMIC segment.
ii) How do I 'make sure' that the kernel has a PT_PHDR segment?
iii) Should I use the MULTIBOOT_ELF_SECTIONS tag or should I try using the kernel program header & segments for dynamic linking with the modules? I feel that using the
MULTIBOOT_ELF_SECTIONS tag may be easier, but I need your advice.

2. You have said that GOT can be found with DT_PLTGOT entry (in dynamic section). But in the documentation, it said that the address can be associated with the GOT OR PLT. Confusing....

I have done some relocation work now. In my modules 'KModuleMain' function, I call a core-kernel's function elf_dbg(). There is only one relocation entry so I just do the R_386_JMP_SLOT relocation
and it works. Is lazy binding required for the kernel? I think that kernel-modules shoudn't face the non-uniformness of timing of function calling, especially because I WILL implement real-time scheduling
support & lazy binding WILL (as I believe) hinder with real-time support. If I don't implement lazy binding AT ALL then I don't have to even touch the GOT or PLT, I am correct?

Thank You Korona, as you have cleared 80% of my doubts and have helped me to relocated the elf_dbg() symbol in my module.

Regards,
Shukant Pal


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Wed Oct 18, 2017 7:05 am 
Offline
Member
Member

Joined: Tue May 13, 2014 3:02 am
Posts: 280
Location: Private, UK
Korona wrote:
There are basically two ways to load ELF code at runtime:
  • Compile the code to an object file and perform the final link during runtime.
  • Compile the code to a shared object, perform dynamic linking at runtime.


There's also a third option (which I use for kernel modules); compile the code to a "relocatable executable", do no runtime linking (only basic fixed-offset relocation) and simply pass a pointer to a dispatch table as a parameter to the entry point of the executable.

Advantages:
  • Very simple; no complex linking code in the kernel, no need to load the kernel's symbol table, etc.
  • Effectively restricts modules to calling the official, public kernel API, not referencing arbitary symbols, making maintenance easier.

Disadvantages:
  • Requires proper specification of the kernel API, rather than it coming "for free" through public symbols.
  • Requires extra work to allow modules to call each other (I have an "extension" API that allows modules to provide extra dispatch tables for this purpose).

_________________
Image


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Thu Oct 19, 2017 7:06 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
Hi,

I have done the relocation for my KTERM module. It is linked to the core-kernel by only on symbol - elf_dbg(). Actually, I didn't search the kernel symbol table for the "elf_dbg" symbol, but just set all found relocation symbols to the value of "elf_dbg" (only one was present, and it was actually for elf_dbg()). Now, I need a mechanism to search my kernel symbol table.

I've worked on doing this. I have using the Multiboot-ELF-Section type (MULTIBOOT_ELF_SECTION) for getting all the section headers & getting the .symtab & .strtab & .shstrtab sections. But, I have also found that my kernel executable DOES NOT contain a .dynamic section OR a .dynsym section. This means it doesn't have any dynamic tags or dynamic symbol table. The question is that how would I move symbols into the dynamic symbol table for linking with kernel modules? Also, Why doesn't my kernel executable contain any .dynamic section (it contains a dynamic segment with VMA equal to 0)?

Regards,
Shukant Pal


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Thu Oct 19, 2017 12:16 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
I never tried to turn my kernel into a dynamic executable (I'm using a microkernel without modules). I'm using dynamic linking in user mode only and there LD automatically generates PT_DYNAMIC (I guess that is because it has to link against my dynamically linked libc). I'd suggest to look at the LD manual and try to get the flags right so that is creates a proper PT_DYNAMIC section.

Regarding your earlier question about lazy binding: No, you don't need lazy binding in the kernel; and as you said, it's probably a good idea to not implement it. You don't even need it in user mode though it will improve application startup time.

SukantPal wrote:
You have said that GOT can be found with DT_PLTGOT entry (in dynamic section). But in the documentation, it said that the address can be associated with the GOT OR PLT.

Yeah, as I said, that entries name is very stupid. I am sure that it is the GOT though. IIRC the x86 ELF supplement clears that up.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Thu Oct 19, 2017 11:48 pm 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
Hi Korona,

Actually I've already read the LD manual. I search for "PT_DYNAMIC" and there was no specific explanation in my notice. Can you help me in finding that? I have also tried creating my own linker script with PHDRS command -

Code:
OUTPUT_FORMAT("elf32-i386")
ENTRY(InitRuntime)

SECTIONS {
   . = 0xc0100000 + SIZEOF_HEADERS;
   KernelStart = .;

   KernelCodeStart = .;
   .text ALIGN (0x1000) : AT(ADDR(.text) - 0xC0000000)
   {
      *(.text)
      *(.rdata)
      *(.rodata)
   } : text
   KernelCodeEnd = .;


   KernelDataStart = .;
   .data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
   {
      *(.data)
   } : data
   KernelDataEnd = .;

   KernelBSSStart = .;
   .bss ALIGN (0x1000) : AT(ADDR(.bss) - 0xC0000000)
   {
      *(COMMON)
      *(.bss)
   } : data
   KernelBSSEnd = .;

   .dynamic ALIGN(0x1000) : AT(ADDR(.) - 0xC0000000)
   {
      *(.dynamic*)
   } :data :dynamic /* Comment: I have also tried :dynamic instead of :data:dynamic */

   KernelEnd = .;
   HALData = .;
}

PHDRS {
   headers PT_PHDR PHDRS;
   text PT_LOAD FILEHDR PHDRS;
   data PT_LOAD;
   dynamic PT_DYNAMIC;
}


readelf -l <Binary> will still show no .dynamic section in the dynamic segment.


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Fri Oct 20, 2017 1:02 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
LD's default linker script also includes (*.dynsym) and (*.dynstr), as well as a few additional sections (see Linux' LD script here). Can you provide the output of readelf -l? You may also need to link with -E to force LD to generate a dynamic symbol table for executables.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Fri Oct 20, 2017 8:03 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
readelf -S circuitk-1.02

Code:
There are 22 section headers, starting at offset 0x128e8:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        c0101000 001000 0067e5 00  AX  0   0 16
  [ 2] .text.__x86.get_p PROGBITS        c01077e5 0077e5 000004 00  AX  0   0  1
  [ 3] .text.__x86.get_p PROGBITS        c01077e9 0077e9 000004 00  AX  0   0  1
  [ 4] .text.__x86.get_p PROGBITS        c01077ed 0077ed 000004 00  AX  0   0  1
  [ 5] .text.__x86.get_p PROGBITS        c01077f1 0077f1 000004 00  AX  0   0  1
  [ 6] .text.__x86.get_p PROGBITS        c01077f5 0077f5 000004 00  AX  0   0  1
  [ 7] .text.__x86.get_p PROGBITS        c01077f9 0077f9 000004 00  AX  0   0  1
  [ 8] .text.__x86.get_p PROGBITS        c01077fd 0077fd 000004 00  AX  0   0  1
  [ 9] .eh_frame         PROGBITS        c0107804 007804 002b38 00   A  0   0  4
  [10] .rodata.str1.1    PROGBITS        c010a33c 00a33c 000396 01 AMS  0   0  1
  [11] .rodata.str1.4    PROGBITS        c010a6d4 00a6d4 0003b0 01 AMS  0   0  4
  [12] .data             PROGBITS        c010b000 00b000 004125 00  WA  0   0 4096
  [13] .got              PROGBITS        c010f128 00f128 000018 04  WA  0   0  4
  [14] .got.plt          PROGBITS        c010f140 00f140 00000c 04  WA  0   0  4
  [15] .data.rel.local   PROGBITS        c010f160 00f160 000128 00  WA  0   0 32
  [16] .data.rel         PROGBITS        c010f2a0 00f2a0 0001b8 00  WA  0   0 32
  [17] .bss              NOBITS          c0110000 00f458 0042a4 00  WA  0   0 32
  [18] .comment          PROGBITS        00000000 00f458 000034 01  MS  0   0  1
  [19] .shstrtab         STRTAB          00000000 01279d 000149 00      0   0  1
  [20] .symtab           SYMTAB          00000000 00f48c 001cb0 10     21 146  4
  [21] .strtab           STRTAB          00000000 01113c 001661 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)


readelf -l circuitk-1.02

WITH THIS LINKER SCRIPT

Code:
OUTPUT_FORMAT("elf32-i386")
ENTRY(InitRuntime)

SECTIONS {
   . = 0xc0100000 + SIZEOF_HEADERS;
   KernelStart = .;

   KernelCodeStart = .;
   .text ALIGN (0x1000) : AT(ADDR(.text) - 0xC0000000)
   {
      *(.text)
      *(.rdata)
      *(.rodata)
   }
   KernelCodeEnd = .;


   KernelDataStart = .;
   .data ALIGN (0x1000) : AT(ADDR(.data) - 0xC0000000)
   {
      *(.data)
   }
   KernelDataEnd = .;

   KernelBSSStart = .;
   .bss ALIGN (0x1000) : AT(ADDR(.bss) - 0xC0000000)
   {
      *(COMMON)
      *(.bss)
      *(.hash)
   }
   KernelBSSEnd = .;

   .dynsym : { *(.dynsym) }
   .dynstr : { *(.dynstr) }
   .hash : { *(.hash) }
   .dynamic : { *(.dynamic) }

   KernelEnd = .;
   HALData = .;
}


Code:
Elf file type is EXEC (Executable file)
Entry point 0xc010105e
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0xc0101000 0x00101000 0x09a84 0x09a84 R E 0x1000
  LOAD           0x00b000 0xc010b000 0x0010b000 0x04458 0x092a4 RW  0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10

Section to Segment mapping:
  Segment Sections...
   00     .text .text.__x86.get_pc_thunk.ax .text.__x86.get_pc_thunk.bx .text.__x86.get_pc_thunk.si .text.__x86.get_pc_thunk.di .text.__x86.get_pc_thunk.dx .text.__x86.get_pc_thunk.bp .text.__x86.get_pc_thunk.cx .eh_frame .rodata.str1.1 .rodata.str1.4
   01     .data .got .got.plt .data.rel.local .data.rel .bss
   02


but with the linker script which I already posted

Code:
Elf file type is EXEC (Executable file)
Entry point 0xc010105e
There are 4 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0xc0100034 0x00100034 0x00080 0x00080 R   0x4
  LOAD           0x000000 0xc0100000 0x00100000 0x0aa84 0x0aa84 R E 0x1000
  LOAD           0x00b000 0xc010b000 0x0010b000 0x04458 0x092a4 RW  0x1000
  DYNAMIC        0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4
readelf: Error: no .dynamic section in the dynamic segment

Section to Segment mapping:
  Segment Sections...
   00     
   01     .text .text.__x86.get_pc_thunk.ax .text.__x86.get_pc_thunk.bx .text.__x86.get_pc_thunk.si .text.__x86.get_pc_thunk.di .text.__x86.get_pc_thunk.dx .text.__x86.get_pc_thunk.bp .text.__x86.get_pc_thunk.cx .eh_frame .rodata.str1.1 .rodata.str1.4
   02     .data .got .got.plt .data.rel.local .data.rel .bss
   03     


For more data, you can download the CircuitKernel source code - https://github.com/SukantPal/CircuitKernel


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Fri Oct 20, 2017 8:10 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
Beware, the code is a little old so some errors will exist.

One more question - Is there a hash table for the .symtab section? For does it exist along with .dynsym only?


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Sat Oct 21, 2017 2:19 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
Hi Guys,

I kind of feel shameless telling you that I had to add the
Code:
-pie
flag to the linker to get the .dynamic, .dynsym, .dynstr sections. I did add them to the linker script before, but still they didn't appear. Does that mean a dynamic binary has to be a Position-Independent-Executable???

Also, for some reason the .dynsym section has corrupt entries, as said by readelf --dyn-syms <executable-name>. Any reasons???


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Sat Oct 21, 2017 2:28 am 
Offline
Member
Member

Joined: Sat Jan 21, 2017 7:35 am
Posts: 35
New update - I HAVE FOUND THE SOLUTION. THE DYNAMIC SYMBOL TABLE WAS CORRUPT BECAUSE I HAD .dynsym, .dynstr, .dynamic... entries in my LINKER SCRIPT. I REMOVED THE ENTRIES AND NOW THE DYNAMIC SYMBOL TABLE IS COMPLETE.

Finishing up, I've some questions to ask -

1. Why doesn't the linux kernel use the .dynsym (dynamic symbol table) for linking kernel modules. It could use the dynamic list for symbols to only keep the exported symbols. Isn't keeping the stupid .ksymtab & whatever kernel sections as seperate useless?

2. Could a kernel modules act as a messenger b/w a user-mode application & the kernel. For example, a library could be mapped in kernel space & user-space. In user-space, the code could read some buffers & send filtered information to application (as desired by it) & in kernel-mode it could ask for more buffers. Also, the kernel & userspace could share some utility shared library like memcpy & and all right?

3. Any more things that I should implement for faster module performance?

4. Any advice on debugging with symbols (on my own in the kernel)...

5. How do I mark this posted as [SOLVED]

Thank You,
Shukant Pal

I appreciate the help given by Korona and other OSDevers.


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Sat Oct 28, 2017 8:25 am 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 641
Location: Ukraine, Bachmut
I guess SukantPal will forgive me for reusing his mostly answered thread? :)

Why making another ELF thread if there is one, quite fresh?

I am writing a utility converting ELF into PE. For using in my FW and OS. And I faced a weird linker behavior. Maybe some of you know is it possible to tell it do things not as dumb. Namely, there is a File Alignment and Section Alignment for executables. First tells how to align sections inside a file as it is stored on disk. The second tells how to put sections in memory. All offsets encoded into instructions of course are valid only when sections are placed with those distances between sections as it was assigned at link time, not as they placed in the file. there, they are compacted for saving space.
When you compile with GCC, for bare metal MIPS at least, without any alignment directives in the linker script, sections get non aligned locations, no page alignment, no sector alignment, just aligned at 4 as for the first symbol lying inside of it. It's weird by itself but OK, linker scripts have ALIGN command, for the output sections (resulting linker generated ones). That's exactly what we need! And everything is good. Except that in the file sections are placed with huge gaps between them too! They aren't aligned there (relative to file start), but the distance between beginnings of two consecutive sections now is Section Alignment in size! What the hell! Why? That placement is supposed to get real only in memory, not in the file.
Basically the problem is the linker puts sections inside a file with the distance == Section Alignment, whereas it has been assigned for sections when they go in memory for execution, not for storage in the file. Why it is doing so and is there a way to tell it not to do that?
Here is the example of linker script for testing.
Code:
MEMORY{
   RegFwSdram :   ORIGIN = 80000000h, LENGTH = 10000000h
}

PHDRS{
   DxeSegment PT_LOAD;
}

ENTRY( DllMain )

SECTIONS{
   . = 80001000h;      /* start of code, VA */
   __start = .;      

   .text . :{      /* Code */
      halefi.o ( .text )
      * ( .text )
   } >RegFwSdram :DxeSegment = 0,

   .rdata ALIGN(0x1000) :{      /* RO data */
      * ( .iat )
      halefi.o ( .rdata )
      * ( .rdata )
      * ( .Strings )
   } >RegFwSdram :DxeSegment

   .data ALIGN(0x1000) :{      /* Data */
      halefi.o ( .data )
      * ( .data )
   } >RegFwSdram :DxeSegment
}

Note, ".text" section is section aligned (0x1000) without the ALIGN, just by setting the position. And in the file it gets "normal" file offset, something like 0x78. Others are ALIGNed and for example .rdata gets 0x1078 offset. and .data - 0x2078. I suspect should .text be explicitly aligned, it would get that huge file offset too. Despite it is stated ALIGN command just adjusts the current position to the nearest upper aligned location. basically the same as manipulation with the "dot" element.

I don't get it, doesn't ELF likner understand the difference between file position and memory position of sections in memory?
And yet, sections must be placed page aligned in memory, no matter hat the executable foramt is. For applying different page attributes, corresponding to section attributes, for CoW etc. Why GCC puts sections not aligned at page? Is it only on bare metal MIPS, or it behaves the same for x86? I don't have the latter to check.

If someone is interested in this utility, I might upload its code or the program itself later. Now it only supports MIPS32 targets. :D I don't know if GCC for bare metal, freestanding, on x86 lets you generate PE/COFF, but for ARM, ARM64 and MIPS32 it doesn't. That's why I do it by myself.
It lets you use PE format for your images. It's a simple utility so you need to decide on your section arrangement with your linker. the utility won't do section merging or reordering. It just translates resulting Elf executable into PE executable. Also, only ET_EXEC elf type is supported, because PE doesn't use PIC approach, or at least I am not using it. As it is extremely complicated and not giving any advantages.
For executables there is a need to generate import information, and for DLLs export information as well. For my assembly written files now, I do it by hand. How to do it with C, that's the question. Not resolved yet. But when it is, the utility is ready for making a proper PE import and export tables. That's all one needs for comfortable dynamic linking. But an input Elf file can not be position independent code, only Elf executable, linked at the desired address.

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Sun Oct 29, 2017 6:06 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
I'm not sure if I understand your question. ALIGN aligns segments in virtual memory. The linker tries to keep virtual memory offsets and file offsets in sync so that mmap() suffices to load the executable, without the need to copy read-only segments from the file to a process-specific chunk of memory.

For example, readelf -l typically prints something like this:
Code:
Elf file type is EXEC (Executable file)
Entry point 0x4064a6
There are 7 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x0000000000000188 0x0000000000000188  R E    0x8
  INTERP         0x00000000000001c8 0x00000000004001c8 0x00000000004001c8
                 0x000000000000001d 0x000000000000001d  R      0x1
      [Requesting program interpreter: /lib/x86_64-managarm/rtdl.so]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000015cac 0x0000000000015cac  R E    0x200000
  LOAD           0x0000000000016000 0x0000000000616000 0x0000000000616000
                 0x00000000000005a8 0x0000000000000898  RW     0x200000
  DYNAMIC        0x0000000000016028 0x0000000000616028 0x0000000000616028
                 0x0000000000000250 0x0000000000000250  RW     0x8
  GNU_EH_FRAME   0x0000000000012fa0 0x0000000000412fa0 0x0000000000412fa0
                 0x00000000000005cc 0x00000000000005cc  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RWE    0x10

Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp
   02     .interp .hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .gcc_except_table
   03     .ctors .dtors .dynamic .got .got.plt .data .bss
   04     .dynamic
   05     .eh_frame_hdr
   06     

And the segments clearly page aligned (to 2 MiB pages).

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Kernel ELF Header - Not Present & Dynamic Linking for Mo
PostPosted: Sun Oct 29, 2017 6:40 am 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 641
Location: Ukraine, Bachmut
Quote:
The linker tries to keep virtual memory offsets and file offsets in sync so that mmap() suffices to load the executable, without the need to copy read-only segments from the file to a process-specific chunk of memory.

This. It's not a big problem for me, since I still will be converting it, but don't you know, is there a way to tell linker to not do so, and keep section placement in the file as compact as possible?

For example in my case the executables are small and file size overhead caused by this behavior is significant (should I use these ELFs). The amount of space on disk (SD card) where I can place the Firmware Volume is small, oppositely, the memory amount is enough. So it would be nice to have a little file and only on loading place sections at aligned positions not caring much about the space.

But anyway, all these efforts were to avoid doing relocations at the translation stage. Now I figured out that it's almost impossible to safely derive image base form ELF file, so I decided to not avoid them, and since, I may not bother with aligning sections at the elf linker stage.
Thank you for your answer.

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 71 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group