added 3 changesets to branch 'refs/remotes/xyzzy-github/x86_64' old head: e453c0f4a7d0014d73e9b499aa1fe813dc64c084 new head: 12b3e8a8a01e04da03da98410425695880e96347 ---------------------------------------------------------------------------- 0efc5e7: Merge branch 'master' into x86_64 bd8b78e: Added a dumb TLS implementation rather than printing an error. Will properly implement TLS soon, for now a "working" implementation is needed for anything to work properly. 12b3e8a: Support x86_64 in the runtime loader. * Added x86_64 linker script and relocation code. * Some 64-bit safety fixes to the heap code. * Added runtime_loader, libroot and bash to the x86_64 image. The boot script will be launched, but will panic shortly after because fork is broken. [ Alex Smith <alex@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 342 files changed, 14120 insertions(+), 7513 deletions(-) build/jam/Haiku64Image | 8 +- build/jam/OptionalBuildFeatures | 32 + build/jam/OptionalPackages | 26 + configure | 2 +- .../inbound_filters/match_header/ru.catkeys | 15 + .../inbound_filters/notifier/ru.catkeys | 10 + .../inbound_filters/spam_filter/ja.catkeys | 4 +- .../mail_daemon/outbound_protocols/smtp/be.catkeys | 5 +- .../mail_daemon/outbound_protocols/smtp/de.catkeys | 5 +- .../mail_daemon/outbound_protocols/smtp/fi.catkeys | 5 +- .../mail_daemon/outbound_protocols/smtp/ja.catkeys | 4 +- .../mail_daemon/outbound_protocols/smtp/nl.catkeys | 5 +- .../mail_daemon/outbound_protocols/smtp/pl.catkeys | 5 +- data/catalogs/add-ons/translators/tga/ru.catkeys | 3 +- .../add-ons/translators/wonderbrush/ru.catkeys | 3 +- data/catalogs/apps/aboutsystem/be.catkeys | 4 +- data/catalogs/apps/aboutsystem/de.catkeys | 4 +- data/catalogs/apps/aboutsystem/ja.catkeys | 4 +- data/catalogs/apps/aboutsystem/ru.catkeys | 5 +- data/catalogs/apps/deskbar/be.catkeys | 4 +- data/catalogs/apps/deskbar/de.catkeys | 4 +- data/catalogs/apps/deskbar/fi.catkeys | 4 +- data/catalogs/apps/deskbar/ja.catkeys | 4 +- data/catalogs/apps/deskbar/pl.catkeys | 3 +- data/catalogs/apps/deskbar/ru.catkeys | 25 +- data/catalogs/apps/deskcalc/ru.catkeys | 5 +- data/catalogs/apps/devices/ru.catkeys | 6 +- data/catalogs/apps/diskprobe/ja.catkeys | 4 +- data/catalogs/apps/diskprobe/ru.catkeys | 3 +- data/catalogs/apps/diskusage/ru.catkeys | 3 +- data/catalogs/apps/expander/ru.catkeys | 6 +- data/catalogs/apps/fontdemo/ru.catkeys | 22 + data/catalogs/apps/icon-o-matic/be.catkeys | 3 +- data/catalogs/apps/icon-o-matic/de.catkeys | 3 +- data/catalogs/apps/icon-o-matic/fi.catkeys | 3 +- data/catalogs/apps/icon-o-matic/ru.catkeys | 4 +- data/catalogs/apps/installer/be.catkeys | 7 +- data/catalogs/apps/installer/de.catkeys | 7 +- data/catalogs/apps/installer/fi.catkeys | 7 +- data/catalogs/apps/installer/ja.catkeys | 7 +- data/catalogs/apps/installer/pl.catkeys | 5 +- data/catalogs/apps/installer/ru.catkeys | 7 +- data/catalogs/apps/launchbox/ru.catkeys | 3 +- data/catalogs/apps/mail/ru.catkeys | 6 +- data/catalogs/apps/mediaconverter/ru.catkeys | 3 +- data/catalogs/apps/mediaplayer/be.catkeys | 3 +- data/catalogs/apps/mediaplayer/de.catkeys | 3 +- data/catalogs/apps/mediaplayer/fi.catkeys | 3 +- data/catalogs/apps/mediaplayer/ja.catkeys | 3 +- data/catalogs/apps/mediaplayer/pl.catkeys | 3 +- data/catalogs/apps/mediaplayer/ru.catkeys | 15 +- data/catalogs/apps/networkstatus/ru.catkeys | 3 +- data/catalogs/apps/packagemanager/ru.catkeys | 2 + data/catalogs/apps/poorman/ru.catkeys | 10 +- data/catalogs/apps/powerstatus/ru.catkeys | 7 +- .../catalogs/apps/screenshot/Screenshot/ru.catkeys | 3 +- data/catalogs/apps/soundrecorder/ru.catkeys | 11 +- data/catalogs/apps/terminal/ru.catkeys | 3 +- data/catalogs/apps/webpositive/ja.catkeys | 112 ++ data/catalogs/apps/workspaces/ru.catkeys | 4 +- data/catalogs/kits/tracker/be.catkeys | 16 +- data/catalogs/kits/tracker/de.catkeys | 9 +- data/catalogs/kits/tracker/el.catkeys | 8 +- data/catalogs/kits/tracker/fi.catkeys | 9 +- data/catalogs/kits/tracker/fr.catkeys | 3 +- data/catalogs/kits/tracker/hi.catkeys | 9 +- data/catalogs/kits/tracker/ja.catkeys | 28 +- data/catalogs/kits/tracker/lt.catkeys | 9 +- data/catalogs/kits/tracker/nb.catkeys | 9 +- data/catalogs/kits/tracker/nl.catkeys | 9 +- data/catalogs/kits/tracker/pl.catkeys | 9 +- data/catalogs/kits/tracker/ru.catkeys | 16 +- data/catalogs/kits/tracker/sk.catkeys | 9 +- data/catalogs/kits/tracker/uk.catkeys | 9 +- data/catalogs/kits/tracker/zh-Hans.catkeys | 3 +- data/catalogs/preferences/3drendering/ru.catkeys | 4 +- data/catalogs/preferences/appearance/be.catkeys | 5 +- data/catalogs/preferences/appearance/de.catkeys | 4 +- data/catalogs/preferences/appearance/fi.catkeys | 4 +- data/catalogs/preferences/appearance/ja.catkeys | 4 +- data/catalogs/preferences/appearance/nl.catkeys | 3 +- data/catalogs/preferences/appearance/pl.catkeys | 4 +- data/catalogs/preferences/appearance/ru.catkeys | 15 +- .../preferences/datatranslations/ru.catkeys | 3 +- data/catalogs/preferences/keymap/nl.catkeys | 6 +- data/catalogs/preferences/keymap/ru.catkeys | 17 +- data/catalogs/preferences/mail/ru.catkeys | 3 +- data/catalogs/preferences/printers/ru.catkeys | 3 +- data/catalogs/preferences/time/ru.catkeys | 5 +- data/catalogs/servers/debug/ru.catkeys | 4 + data/catalogs/servers/mail/ru.catkeys | 8 + data/catalogs/tests/kits/opengl/glinfo/be.catkeys | 9 + data/catalogs/tests/kits/opengl/glinfo/fi.catkeys | 9 + data/catalogs/tests/kits/opengl/glinfo/fr.catkeys | 9 + data/catalogs/tests/kits/opengl/glinfo/lt.catkeys | 9 + data/catalogs/tests/kits/opengl/glinfo/sk.catkeys | 9 + .../devices/keyboard/TeamMonitorWindow.cpp | 10 +- .../devices/keyboard/TeamMonitorWindow.h | 1 + .../kernel/drivers/ports/usb_serial/Jamfile | 1 + [ *** stats truncated: 243 lines dropped *** ] ############################################################################ Commit: 0efc5e72dc9502e0121dcd1aca8dfa0f4747d259 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sat Jul 28 15:29:41 2012 UTC Merge branch 'master' into x86_64 ---------------------------------------------------------------------------- ############################################################################ Commit: bd8b78e6eedb24ab48771d18db6e091488cf53d3 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sat Jul 28 15:54:30 2012 UTC Added a dumb TLS implementation rather than printing an error. Will properly implement TLS soon, for now a "working" implementation is needed for anything to work properly. ---------------------------------------------------------------------------- diff --git a/src/system/libroot/os/arch/x86_64/tls.cpp b/src/system/libroot/os/arch/x86_64/tls.cpp index 794c422..c45b7f7 100644 --- a/src/system/libroot/os/arch/x86_64/tls.cpp +++ b/src/system/libroot/os/arch/x86_64/tls.cpp @@ -18,33 +18,37 @@ #include <assert.h> +static int32 gNextSlot = TLS_FIRST_FREE_SLOT; +static void* gSlots[TLS_MAX_KEYS]; + + int32 tls_allocate(void) { - assert(0 && "tls_allocate: not implemented"); - return 0; + int32 next = atomic_add(&gNextSlot, 1); + if (next >= TLS_MAX_KEYS) + return B_NO_MEMORY; + + return next; } void* tls_get(int32 index) { - assert(0 && "tls_get: not implemented"); - return NULL; + return gSlots[index]; } void** tls_address(int32 index) { - assert(0 && "tls_address: not implemented"); - return NULL; + return &gSlots[index]; } void tls_set(int32 index, void* value) { - assert(0 && "tls_set: not implemented"); + gSlots[index] = value; } - ############################################################################ Commit: 12b3e8a8a01e04da03da98410425695880e96347 Author: Alex Smith <alex@xxxxxxxxxxxxxxxx> Date: Sat Jul 28 15:57:56 2012 UTC Support x86_64 in the runtime loader. * Added x86_64 linker script and relocation code. * Some 64-bit safety fixes to the heap code. * Added runtime_loader, libroot and bash to the x86_64 image. The boot script will be launched, but will panic shortly after because fork is broken. ---------------------------------------------------------------------------- diff --git a/build/jam/Haiku64Image b/build/jam/Haiku64Image index 1b126d4..d887b46 100644 --- a/build/jam/Haiku64Image +++ b/build/jam/Haiku64Image @@ -19,7 +19,7 @@ if $(HAIKU_ATA_STACK) = 1 { IDE_ONLY = "" ; } -SYSTEM_BIN = ; +SYSTEM_BIN = bash ; SYSTEM_APPS = ; @@ -27,7 +27,7 @@ SYSTEM_PREFERENCES = ; SYSTEM_DEMOS = ; -SYSTEM_LIBS = ; +SYSTEM_LIBS = libroot.so ; PRIVATE_SYSTEM_LIBS = ; @@ -74,13 +74,13 @@ AddLibrariesToHaikuHybridImage system lib AddFilesToHaikuImage system servers : $(SYSTEM_SERVERS) ; # apps -#AddFilesToHaikuImage system : runtime_loader ; +AddFilesToHaikuImage system : runtime_loader ; AddFilesToHaikuImage system bin : $(SYSTEM_BIN) ; AddFilesToHaikuImage system apps : $(SYSTEM_APPS) ; AddFilesToHaikuImage system preferences : $(SYSTEM_PREFERENCES) ; AddFilesToHaikuImage system demos : $(SYSTEM_DEMOS) ; -#AddSymlinkToHaikuImage system bin : bash : sh ; +AddSymlinkToHaikuImage system bin : bash : sh ; #AddSymlinkToHaikuImage system bin : less : more ; #AddSymlinkToHaikuImage system bin : gzip : gunzip ; #AddSymlinkToHaikuImage system bin : gzip : zcat ; diff --git a/src/system/ldscripts/x86_64/runtime_loader.ld b/src/system/ldscripts/x86_64/runtime_loader.ld new file mode 100644 index 0000000..a83a6de --- /dev/null +++ b/src/system/ldscripts/x86_64/runtime_loader.ld @@ -0,0 +1,53 @@ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) + +ENTRY(runtime_loader) +SEARCH_DIR("libgcc"); +SECTIONS +{ + . = 0x00200000 + SIZEOF_HEADERS; + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } + .rela.got : { *(.rela.got) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0x90909090 + .plt : { *(.plt) } + + /* text/read-only data */ + .text : { *(.text .text.* .gnu.linkonce.t.*) } =0x90909090 + + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + + /* writable data */ + . = ALIGN (CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)); + __data_start = .; + PROVIDE(_data_start = .); + .data : { *(.data .gnu.linkonce.d.*) } + + __ctor_list = .; + PROVIDE (_ctor_list = .); + .ctors : { *(.ctors) } + PROVIDE (__ctor_end = .); + + + /* uninitialized data (in same segment as writable data) */ + PROVIDE (__bss_start = .); + .bss : { *(.bss) } + + . = ALIGN(0x1000); + PROVIDE (_end = .); + + /* Strip unnecessary stuff */ + /DISCARD/ : { *(.comment .note .eh_frame .dtors) } +} diff --git a/src/system/runtime_loader/arch/x86_64/Jamfile b/src/system/runtime_loader/arch/x86_64/Jamfile new file mode 100644 index 0000000..a894a0c --- /dev/null +++ b/src/system/runtime_loader/arch/x86_64/Jamfile @@ -0,0 +1,14 @@ +SubDir HAIKU_TOP src system runtime_loader arch x86_64 ; + +UsePrivateHeaders runtime_loader ; +UsePrivateSystemHeaders ; + +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; + +StaticLibrary libruntime_loader_$(TARGET_ARCH).a : + arch_relocate.cpp + : + <src!system!libroot!os!arch!$(TARGET_ARCH)>atomic.o + <src!system!libroot!os!arch!$(TARGET_ARCH)>thread.o + <src!system!libroot!posix!string!arch!$(TARGET_ARCH)>arch_string.o +; diff --git a/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp b/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp new file mode 100644 index 0000000..7148c2e --- /dev/null +++ b/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp @@ -0,0 +1,96 @@ +/* + * Copyright 2012, Alex Smith, alex@xxxxxxxxxxxxxxxxx + * Distributed under the terms of the MIT License. + */ + + +#include "runtime_loader_private.h" + +#include <runtime_loader.h> + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + + +static status_t +relocate_rela(image_t* rootImage, image_t* image, Elf64_Rela* rel, + size_t relLength, SymbolLookupCache* cache) +{ + for (size_t i = 0; i < relLength / sizeof(Elf64_Rela); i++) { + int type = ELF64_R_TYPE(rel[i].r_info); + int symIndex = ELF64_R_SYM(rel[i].r_info); + Elf64_Addr symAddr = 0; + + // Resolve the symbol, if any. + if (symIndex != 0) { + Elf64_Sym* sym = SYMBOL(image, symIndex); + + status_t status = resolve_symbol(rootImage, image, sym, cache, + &symAddr); + if (status != B_OK) { + TRACE(("resolve symbol \"%s\" returned: %" B_PRId32 "\n", + SYMNAME(image, sym), status)); + printf("resolve symbol \"%s\" returned: %" B_PRId32 "\n", + SYMNAME(image, sym), status); + return status; + } + } + + // Address of the relocation. + Elf64_Addr relocAddr = image->regions[0].delta + rel[i].r_offset; + + // Calculate the relocation value. + Elf64_Addr relocValue; + switch(type) { + case R_X86_64_NONE: + continue; + case R_X86_64_64: + case R_X86_64_GLOB_DAT: + case R_X86_64_JUMP_SLOT: + relocValue = symAddr + rel[i].r_addend; + break; + case R_X86_64_PC32: + relocValue = symAddr + rel[i].r_addend - rel[i].r_offset; + break; + case R_X86_64_RELATIVE: + relocValue = image->regions[0].delta + rel[i].r_addend; + break; + default: + TRACE(("unhandled relocation type %d\n", type)); + return B_BAD_DATA; + } + + *(Elf64_Addr *)relocAddr = relocValue; + } + + return B_OK; +} + + +status_t +arch_relocate_image(image_t* rootImage, image_t* image, + SymbolLookupCache* cache) +{ + status_t status; + + // No REL on x86_64. + + // Perform RELA relocations. + if (image->rela) { + status = relocate_rela(rootImage, image, image->rela, image->rela_len, + cache); + if (status != B_OK) + return status; + } + + // PLT relocations (they are RELA on x86_64). + if (image->pltrel) { + status = relocate_rela(rootImage, image, (Elf64_Rela*)image->pltrel, + image->pltrel_len, cache); + if (status != B_OK) + return status; + } + + return B_OK; +} diff --git a/src/system/runtime_loader/heap.cpp b/src/system/runtime_loader/heap.cpp index 03346a9..02dc286 100644 --- a/src/system/runtime_loader/heap.cpp +++ b/src/system/runtime_loader/heap.cpp @@ -35,11 +35,11 @@ static const size_t kInitialHeapSize = 65536; struct free_chunk { - uint32 size; + size_t size; free_chunk *next; - uint32 Size() const; - free_chunk *Split(uint32 splitSize); + size_t Size() const; + free_chunk *Split(size_t splitSize); bool IsTouching(free_chunk *link); free_chunk *Join(free_chunk *link); void Remove(free_chunk *previous = NULL); @@ -50,7 +50,7 @@ struct free_chunk { }; -static uint32 sAvailable; +static size_t sAvailable; static free_chunk sFreeAnchor; @@ -58,10 +58,10 @@ static free_chunk sFreeAnchor; * in this chunk. */ -uint32 +size_t free_chunk::Size() const { - return size - sizeof(uint32); + return size - sizeof(size_t); } @@ -70,13 +70,13 @@ free_chunk::Size() const */ free_chunk * -free_chunk::Split(uint32 splitSize) +free_chunk::Split(size_t splitSize) { - free_chunk *chunk = (free_chunk *)((uint8 *)this + sizeof(uint32) + splitSize); - chunk->size = size - splitSize - sizeof(uint32); + free_chunk *chunk = (free_chunk *)((uint8 *)this + sizeof(size_t) + splitSize); + chunk->size = size - splitSize - sizeof(size_t); chunk->next = next; - size = splitSize + sizeof(uint32); + size = splitSize + sizeof(size_t); return chunk; } @@ -167,7 +167,7 @@ free_chunk::AllocatedAddress() const free_chunk * free_chunk::SetToAllocated(void *allocated) { - return (free_chunk *)((uint8 *)allocated - sizeof(uint32)); + return (free_chunk *)((uint8 *)allocated - sizeof(size_t)); } @@ -183,7 +183,7 @@ add_area(size_t size) if (area < B_OK) return area; - sAvailable += size - sizeof(uint32); + sAvailable += size - sizeof(size_t); // declare the whole heap as one chunk, and add it // to the free list @@ -198,7 +198,7 @@ add_area(size_t size) static status_t -grow_heap(uint32 bytes) +grow_heap(size_t bytes) { // align the area size to an 32768 bytes boundary bytes = (bytes + 32767) & ~32767; @@ -295,10 +295,10 @@ restart: goto restart; } - if (chunk->Size() > size + sizeof(free_chunk) + 4) { + if (chunk->Size() > size + sizeof(free_chunk) + sizeof(size_t)) { // if this chunk is bigger than the requested size, // we split it to form two chunks (with a minimal - // size of 4 allocatable bytes). + // size of sizeof(size_t) allocatable bytes). free_chunk *freeChunk = chunk->Split(size); last->next = freeChunk; @@ -312,7 +312,7 @@ restart: last->next = chunk->next; } - sAvailable -= size + sizeof(uint32); + sAvailable -= size + sizeof(size_t); return chunk->AllocatedAddress(); } diff --git a/src/system/runtime_loader/images.cpp b/src/system/runtime_loader/images.cpp index 0f504a9..6c6c460 100644 --- a/src/system/runtime_loader/images.cpp +++ b/src/system/runtime_loader/images.cpp @@ -23,8 +23,16 @@ #include "runtime_loader_private.h" -#define RLD_PROGRAM_BASE 0x00200000 - /* keep in sync with app ldscript */ +// keep in sync with app ldscript +#ifdef __x86_64__ + // runtime_loader potentially occupies 0x200000 - 0x600000 due to large + // page segment alignment. +# define RLD_PROGRAM_BASE 0x600000 +# define MAX_PAGE_SIZE 0x200000 +#else +# define RLD_PROGRAM_BASE 0x200000 +# define MAX_PAGE_SIZE B_PAGE_SIZE +#endif bool gInvalidImageIDs; @@ -319,7 +327,7 @@ map_image(int fd, char const* path, image_t* image, bool fixed) // Check whether the segments have an unreasonable amount of unused space // inbetween. - if (reservedSize > length + 8 * 1024) + if (reservedSize > length + MAX_PAGE_SIZE * 2) return B_BAD_DATA; // reserve that space and allocate the areas from that one