mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Handle ELF notes during program load.
This commit is contained in:
parent
86dc1c849e
commit
fdcfb1f2da
4 changed files with 128 additions and 8 deletions
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013.
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2013, 2014.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sortix/elf-note.h>
|
||||
#include <sortix/mman.h>
|
||||
|
||||
#include <sortix/kernel/kernel.h>
|
||||
|
@ -48,7 +49,8 @@ namespace ELF {
|
|||
// headers may vary depending on the ELF header and that using a simple
|
||||
// table indexation isn't enough.
|
||||
|
||||
addr_t Construct32(Process* process, const uint8_t* file, size_t filelen)
|
||||
addr_t Construct32(Process* process, const uint8_t* file, size_t filelen,
|
||||
Auxiliary* aux)
|
||||
{
|
||||
if ( filelen < sizeof(Header32) )
|
||||
return 0;
|
||||
|
@ -88,6 +90,38 @@ addr_t Construct32(Process* process, const uint8_t* file, size_t filelen)
|
|||
for ( uint16_t i = 0; i < numprogheaders; i++ )
|
||||
{
|
||||
const ProgramHeader32* pht = &(phtbl[i]);
|
||||
if ( pht->type == PT_TLS )
|
||||
{
|
||||
aux->tls_file_offset = pht->offset;
|
||||
aux->tls_file_size = pht->filesize;
|
||||
aux->tls_mem_size = pht->memorysize;
|
||||
aux->tls_mem_align = pht->align;
|
||||
continue;
|
||||
}
|
||||
if ( pht->type == PT_NOTE )
|
||||
{
|
||||
uintptr_t notes_addr = (uintptr_t) file + pht->offset;
|
||||
size_t notes_offset = 0;
|
||||
while ( notes_offset < pht->filesize )
|
||||
{
|
||||
uintptr_t note = notes_addr + notes_offset;
|
||||
uint32_t namesz = *(uint32_t*) (note + 0);
|
||||
uint32_t descsz = *(uint32_t*) (note + 4);
|
||||
uint32_t type = *(uint32_t*) (note + 8);
|
||||
uint32_t namesz_aligned = -(-namesz & ~(4U - 1));
|
||||
uint32_t descsz_aligned = -(-descsz & ~(4U - 1));
|
||||
size_t note_size = 12 + namesz_aligned + descsz_aligned;
|
||||
notes_offset += note_size;
|
||||
const char* name = (const char*) (note + 12);
|
||||
uintptr_t desc = note + 12 + namesz_aligned;
|
||||
if ( strcmp(name, "Sortix") == 0 )
|
||||
{
|
||||
(void) desc;
|
||||
(void) type;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( pht->type != PT_LOAD )
|
||||
continue;
|
||||
addr_t virtualaddr = pht->virtualaddr;
|
||||
|
@ -210,12 +244,14 @@ addr_t Construct32(Process* process, const uint8_t* file, size_t filelen)
|
|||
return entry;
|
||||
}
|
||||
|
||||
addr_t Construct64(Process* process, const uint8_t* file, size_t filelen)
|
||||
addr_t Construct64(Process* process, const uint8_t* file, size_t filelen,
|
||||
Auxiliary* aux)
|
||||
{
|
||||
#if !defined(__x86_64__)
|
||||
(void) process;
|
||||
(void) file;
|
||||
(void) filelen;
|
||||
(void) aux;
|
||||
return errno = ENOEXEC, 0;
|
||||
#else
|
||||
if ( filelen < sizeof(Header64) )
|
||||
|
@ -256,6 +292,38 @@ addr_t Construct64(Process* process, const uint8_t* file, size_t filelen)
|
|||
for ( uint16_t i = 0; i < numprogheaders; i++ )
|
||||
{
|
||||
const ProgramHeader64* pht = &(phtbl[i]);
|
||||
if ( pht->type == PT_TLS )
|
||||
{
|
||||
aux->tls_file_offset = pht->offset;
|
||||
aux->tls_file_size = pht->filesize;
|
||||
aux->tls_mem_size = pht->memorysize;
|
||||
aux->tls_mem_align = pht->align;
|
||||
continue;
|
||||
}
|
||||
if ( pht->type == PT_NOTE )
|
||||
{
|
||||
uintptr_t notes_addr = (uintptr_t) file + pht->offset;
|
||||
size_t notes_offset = 0;
|
||||
while ( notes_offset < pht->filesize )
|
||||
{
|
||||
uintptr_t note = notes_addr + notes_offset;
|
||||
uint32_t namesz = *(uint32_t*) (note + 0);
|
||||
uint32_t descsz = *(uint32_t*) (note + 4);
|
||||
uint32_t type = *(uint32_t*) (note + 8);
|
||||
uint32_t namesz_aligned = -(-namesz & ~(4U - 1));
|
||||
uint32_t descsz_aligned = -(-descsz & ~(4U - 1));
|
||||
size_t note_size = 12 + namesz_aligned + descsz_aligned;
|
||||
notes_offset += note_size;
|
||||
const char* name = (const char*) (note + 12);
|
||||
uintptr_t desc = note + 12 + namesz_aligned;
|
||||
if ( strcmp(name, "Sortix") == 0 )
|
||||
{
|
||||
(void) desc;
|
||||
(void) type;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( pht->type != PT_LOAD )
|
||||
continue;
|
||||
addr_t virtualaddr = pht->virtualaddr;
|
||||
|
@ -379,7 +447,8 @@ addr_t Construct64(Process* process, const uint8_t* file, size_t filelen)
|
|||
#endif
|
||||
}
|
||||
|
||||
addr_t Construct(Process* process, const void* file, size_t filelen)
|
||||
addr_t Construct(Process* process, const void* file, size_t filelen,
|
||||
Auxiliary* aux)
|
||||
{
|
||||
if ( filelen < sizeof(Header) )
|
||||
return errno = ENOEXEC, 0;
|
||||
|
@ -390,10 +459,12 @@ addr_t Construct(Process* process, const void* file, size_t filelen)
|
|||
header->magic[2] == 'L' && header->magic[3] == 'F' ) )
|
||||
return errno = ENOEXEC, 0;
|
||||
|
||||
memset(aux, 0, sizeof(*aux));
|
||||
|
||||
switch ( header->fileclass )
|
||||
{
|
||||
case CLASS32: return Construct32(process, (const uint8_t*) file, filelen);
|
||||
case CLASS64: return Construct64(process, (const uint8_t*) file, filelen);
|
||||
case CLASS32: return Construct32(process, (const uint8_t*) file, filelen, aux);
|
||||
case CLASS64: return Construct64(process, (const uint8_t*) file, filelen, aux);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
15
kernel/elf.h
15
kernel/elf.h
|
@ -25,12 +25,23 @@
|
|||
#ifndef SORTIX_ELF_H
|
||||
#define SORTIX_ELF_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Sortix {
|
||||
|
||||
class Process;
|
||||
|
||||
namespace ELF {
|
||||
|
||||
struct Auxiliary
|
||||
{
|
||||
size_t tls_file_offset;
|
||||
size_t tls_file_size;
|
||||
size_t tls_mem_size;
|
||||
size_t tls_mem_align;
|
||||
};
|
||||
|
||||
struct Header
|
||||
{
|
||||
unsigned char magic[4];
|
||||
|
@ -159,6 +170,7 @@ const uint32_t PT_INTERP = 3;
|
|||
const uint32_t PT_NOTE = 4;
|
||||
const uint32_t PT_SHLIB = 5;
|
||||
const uint32_t PT_PHDR = 6;
|
||||
const uint32_t PT_TLS = 7;
|
||||
const uint32_t PT_LOPROC = 0x70000000;
|
||||
const uint32_t PT_HIPROC = 0x7FFFFFFF;
|
||||
|
||||
|
@ -188,7 +200,8 @@ struct Symbol64
|
|||
|
||||
// Reads the elf file into the current address space and returns the entry
|
||||
// address of the program, or 0 upon failure.
|
||||
addr_t Construct(Process* process, const void* file, size_t filelen);
|
||||
addr_t Construct(Process* process, const void* file, size_t filelen,
|
||||
Auxiliary* aux);
|
||||
|
||||
} // namespace ELF
|
||||
} // namespace Sortix
|
||||
|
|
34
kernel/include/sortix/elf-note.h
Normal file
34
kernel/include/sortix/elf-note.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
|
||||
Copyright(C) Jonas 'Sortie' Termansen 2014.
|
||||
|
||||
This file is part of Sortix.
|
||||
|
||||
Sortix is free software: you can redistribute it and/or modify it under the
|
||||
terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
Sortix. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
sortix/elf-note.h
|
||||
Declares type constants for the Sortix ELF notes.
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef INCLUDE_SORTIX_ELF_NOTE_H
|
||||
#define INCLUDE_SORTIX_ELF_NOTE_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
|
@ -747,7 +747,9 @@ int Process::Execute(const char* programname, const uint8_t* program,
|
|||
if ( !programname_clone )
|
||||
return -1;
|
||||
|
||||
addr_t entry = ELF::Construct(CurrentProcess(), program, programsize);
|
||||
ELF::Auxiliary aux;
|
||||
|
||||
addr_t entry = ELF::Construct(CurrentProcess(), program, programsize, &aux);
|
||||
if ( !entry ) { delete[] programname_clone; return -1; }
|
||||
|
||||
delete[] program_image_path;
|
||||
|
|
Loading…
Reference in a new issue