Ticket #6307: haiku_loader.elf64support.patch

File haiku_loader.elf64support.patch, 35.8 KB (added by nmentley, 14 years ago)

added .patch extension to previously uploaded file

  • src/system/boot/platform/bios_ia32/smp.cpp

     
    472472        uint32 j;
    473473
    474474        // set this stack up
    475         finalStack = (uint32 *)gKernelArgs.cpu_kstack[i].start;
     475        finalStack = (uint32 *)(addr_t)gKernelArgs.cpu_kstack[i].start;
    476476        memset((uint8*)finalStack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE, 0,
    477477            KERNEL_STACK_SIZE);
    478478        tempStack = (finalStack
  • src/system/boot/loader/elf.cpp

     
    1111#include <boot/stage2.h>
    1212#include <driver_settings.h>
    1313#include <elf32.h>
     14#include <elf64.h>
    1415#include <kernel.h>
    1516
    1617#include <unistd.h>
     
    6061
    6162
    6263static status_t
     64verify_elf64_header(struct Elf64_Ehdr &header)
     65{
     66    if (memcmp(header.e_ident, ELF_MAGIC, 4) != 0
     67        || header.e_ident[4] != ELFCLASS64
     68        || header.e_phoff == 0
     69        || !header.IsHostEndian()
     70        || header.e_phentsize != sizeof(struct Elf64_Phdr))
     71        return B_BAD_TYPE;
     72
     73    return B_OK;
     74}
     75
     76
     77static status_t
    6378elf_parse_dynamic_section(struct preloaded_image *image)
    6479{
    6580    image->syms = 0;
     
    7186    image->pltrel_len = 0;
    7287    image->pltrel_type = 0;
    7388
    74     struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_section.start;
     89    struct Elf32_Dyn *d = (struct Elf32_Dyn *)(addr_t)image->dynamic_section.start;
    7590    if (!d)
    7691        return B_ERROR;
    7792
     
    123138
    124139
    125140static status_t
     141elf64_parse_dynamic_section(struct preloaded_image *image)
     142{
     143    image->syms64 = 0;
     144    image->rel64 = 0;
     145    image->rel_len = 0;
     146    image->rela64 = 0;
     147    image->rela_len = 0;
     148    image->pltrel64 = 0;
     149    image->pltrel_len = 0;
     150    image->pltrel_type = 0;
     151
     152    struct Elf64_Dyn *d = (struct Elf64_Dyn *)(addr_t)image->dynamic_section.start;
     153    if (!d)
     154        return B_ERROR;
     155
     156    for (int i = 0; d[i].d_tag != DT_NULL; i++) {
     157        switch (d[i].d_tag) {
     158            case DT_HASH:
     159            case DT_STRTAB:
     160                break;
     161            case DT_SYMTAB:
     162                image->syms64 = (struct Elf64_Sym *)(d[i].d_un.d_ptr
     163                    + image->text_region.delta);
     164                break;
     165            case DT_REL:
     166                image->rel64 = (struct Elf64_Rel *)(d[i].d_un.d_ptr
     167                    + image->text_region.delta);
     168                break;
     169            case DT_RELSZ:
     170                image->rel_len = d[i].d_un.d_val;
     171                break;
     172            case DT_RELA:
     173                image->rela64 = (struct Elf64_Rela *)(d[i].d_un.d_ptr
     174                    + image->text_region.delta);
     175                break;
     176            case DT_RELASZ:
     177                image->rela_len = d[i].d_un.d_val;
     178                break;
     179            case DT_JMPREL:
     180                image->pltrel64 = (struct Elf64_Rel *)(d[i].d_un.d_ptr
     181                    + image->text_region.delta);
     182                break;
     183            case DT_PLTRELSZ:
     184                image->pltrel_len = d[i].d_un.d_val;
     185                break;
     186            case DT_PLTREL:
     187                image->pltrel_type = d[i].d_un.d_val;
     188                break;
     189
     190            default:
     191                continue;
     192        }
     193    }
     194
     195    // lets make sure we found all the required sections
     196    if (image->syms64 == NULL)
     197        return B_ERROR;
     198
     199    return B_OK;
     200}
     201
     202
     203static status_t
    126204load_elf_symbol_table(int fd, preloaded_image *image)
    127205{
    128206    struct Elf32_Ehdr &elfHeader = image->elf_header;
     
    224302}
    225303
    226304
     305static status_t
     306load_elf64_symbol_table(int fd, preloaded_image *image)
     307{
     308    struct Elf64_Ehdr &elfHeader = image->elf_header64;
     309    Elf64_Sym *symbolTable = NULL;
     310    Elf64_Shdr *stringHeader = NULL;
     311    uint32 numSymbols = 0;
     312    char *stringTable;
     313    status_t status;
     314
     315    // get section headers
     316
     317    ssize_t size = elfHeader.e_shnum * elfHeader.e_shentsize;
     318    Elf64_Shdr *sectionHeaders = (struct Elf64_Shdr *)malloc(size);
     319    if (sectionHeaders == NULL) {
     320        dprintf("error allocating space for section headers\n");
     321        return B_NO_MEMORY;
     322    }
     323
     324    ssize_t length = read_pos(fd, elfHeader.e_shoff, sectionHeaders, size);
     325    if (length < size) {
     326        TRACE(("error reading in program headers\n"));
     327        status = B_ERROR;
     328        goto error1;
     329    }
     330
     331    // find symbol table in section headers
     332
     333    for (int32 i = 0; i < elfHeader.e_shnum; i++) {
     334        if (sectionHeaders[i].sh_type == SHT_SYMTAB) {
     335            stringHeader = &sectionHeaders[sectionHeaders[i].sh_link];
     336
     337            if (stringHeader->sh_type != SHT_STRTAB) {
     338                TRACE(("doesn't link to string table\n"));
     339                status = B_BAD_DATA;
     340                goto error1;
     341            }
     342
     343            // read in symbol table
     344            symbolTable = (Elf64_Sym *)kernel_args_malloc(
     345                size = sectionHeaders[i].sh_size);
     346            if (symbolTable == NULL) {
     347                status = B_NO_MEMORY;
     348                goto error1;
     349            }
     350
     351            length = read_pos(fd, sectionHeaders[i].sh_offset, symbolTable,
     352                size);
     353            if (length < size) {
     354                TRACE(("error reading in symbol table\n"));
     355                status = B_ERROR;
     356                goto error1;
     357            }
     358
     359            numSymbols = size / sizeof(Elf64_Sym);
     360            break;
     361        }
     362    }
     363
     364    if (symbolTable == NULL) {
     365        TRACE(("no symbol table\n"));
     366        status = B_BAD_VALUE;
     367        goto error1;
     368    }
     369
     370    // read in string table
     371
     372    stringTable = (char *)kernel_args_malloc(size = stringHeader->sh_size);
     373    if (stringTable == NULL) {
     374        status = B_NO_MEMORY;
     375        goto error2;
     376    }
     377
     378    length = read_pos(fd, stringHeader->sh_offset, stringTable, size);
     379    if (length < size) {
     380        TRACE(("error reading in string table\n"));
     381        status = B_ERROR;
     382        goto error3;
     383    }
     384
     385    TRACE(("loaded %ld debug symbols\n", numSymbols));
     386
     387    // insert tables into image
     388    image->debug_symbols64 = symbolTable;
     389    image->num_debug_symbols = numSymbols;
     390    image->debug_string_table = stringTable;
     391    image->debug_string_table_size = size;
     392
     393    free(sectionHeaders);
     394    return B_OK;
     395
     396error3:
     397    kernel_args_free(stringTable);
     398error2:
     399    kernel_args_free(symbolTable);
     400error1:
     401    free(sectionHeaders);
     402
     403    return status;
     404}
     405
    227406status_t
    228 elf_load_image(int fd, preloaded_image *image)
     407elf32_load_image(int fd, preloaded_image *image)
    229408{
    230409    size_t totalSize;
    231410    status_t status;
    232411
    233     TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image));
    234 
    235412    struct Elf32_Ehdr &elfHeader = image->elf_header;
    236 
    237413    ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr));
    238     if (length < (ssize_t)sizeof(Elf32_Ehdr))
    239         return B_BAD_TYPE;
    240414
    241     status = verify_elf_header(elfHeader);
    242     if (status < B_OK)
    243         return status;
    244 
    245415    ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
    246416    Elf32_Phdr *programHeaders = (struct Elf32_Phdr *)malloc(size);
    247417    if (programHeaders == NULL) {
     
    407577    return status;
    408578}
    409579
     580status_t
     581elf64_load_image(int fd, preloaded_image *image)
     582{
     583    size_t totalSize;
     584    status_t status;
    410585
     586    struct Elf64_Ehdr &elfHeader = image->elf_header64;
     587    ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf64_Ehdr));
     588
     589    ssize_t size = elfHeader.e_phnum * elfHeader.e_phentsize;
     590    Elf64_Phdr *programHeaders = (struct Elf64_Phdr *)malloc(size);
     591    if (programHeaders == NULL) {
     592        dprintf("error allocating space for program headers\n");
     593        return B_NO_MEMORY;
     594    }
     595
     596    length = read_pos(fd, elfHeader.e_phoff, programHeaders, size);
     597    if (length < size) {
     598        TRACE(("error reading in program headers\n"));
     599        status = B_ERROR;
     600        goto error1;
     601    }
     602
     603    // create an area large enough to hold the image
     604
     605    image->data_region.size = 0;
     606    image->text_region.size = 0;
     607
     608    for (int32 i = 0; i < elfHeader.e_phnum; i++) {
     609        Elf64_Phdr &header = programHeaders[i];
     610
     611        switch (header.p_type) {
     612            case PT_LOAD:
     613                break;
     614            case PT_DYNAMIC:
     615                image->dynamic_section.start = header.p_vaddr;
     616                image->dynamic_section.size = header.p_memsz;
     617                continue;
     618            case PT_INTERP:
     619            case PT_PHDR:
     620                // known but unused type
     621                continue;
     622            default:
     623                dprintf("unhandled pheader type 0x%lx\n", header.p_type);
     624                continue;
     625        }
     626
     627        elf_region *region;
     628        if (header.IsReadWrite()) {
     629            if (image->data_region.size != 0) {
     630                dprintf("elf: rw already handled!\n");
     631                continue;
     632            }
     633            region = &image->data_region;
     634        } else if (header.IsExecutable()) {
     635            if (image->text_region.size != 0) {
     636                dprintf("elf: ro already handled!\n");
     637                continue;
     638            }
     639            region = &image->text_region;
     640        } else
     641            continue;
     642
     643        region->start = ROUNDDOWN(header.p_vaddr, B_PAGE_SIZE);
     644        region->size = ROUNDUP(header.p_memsz + (header.p_vaddr % B_PAGE_SIZE),
     645            B_PAGE_SIZE);
     646        region->delta = -region->start;
     647
     648        TRACE(("segment %d: start = %p, size = %lu, delta = %lx\n", i,
     649            region->start, region->size, region->delta));
     650    }
     651    image->text_region.size = 1;
     652    // found both, text and data?
     653    if (image->data_region.size == 0 || image->text_region.size == 0) {
     654        dprintf("Couldn't find both text and data segment!\n");
     655        status = B_BAD_DATA;
     656        goto error1;
     657    }
     658
     659    // get the segment order
     660    elf_region *firstRegion;
     661    elf_region *secondRegion;
     662    if (image->text_region.start < image->data_region.start) {
     663        firstRegion = &image->text_region;
     664        secondRegion = &image->data_region;
     665    } else {
     666        firstRegion = &image->data_region;
     667        secondRegion = &image->text_region;
     668    }
     669
     670    // Check whether the segments have an unreasonable amount of unused space
     671    // inbetween.
     672    totalSize = secondRegion->start + secondRegion->size - firstRegion->start;
     673/*  if (totalSize > image->text_region.size + image->data_region.size
     674        + 8 * 1024) {
     675        status = B_BAD_DATA;
     676        goto error1;
     677    }
     678*/
     679    // The kernel and the modules are relocatable, thus
     680    // platform_allocate_region() can automatically allocate an address,
     681    // but shall prefer the specified base address.
     682    if (platform_allocate_region((void **)&firstRegion->start, totalSize,
     683            B_READ_AREA | B_WRITE_AREA, false) < B_OK) {
     684        status = B_NO_MEMORY;
     685        goto error1;
     686    }
     687
     688    // initialize the region pointers to the allocated region
     689    secondRegion->start += firstRegion->start + firstRegion->delta;
     690
     691    image->data_region.delta += image->data_region.start;
     692    image->text_region.delta += image->text_region.start;
     693
     694    // load program data
     695
     696    for (int i = 0; i < elfHeader.e_phnum; i++) {
     697        Elf64_Phdr &header = programHeaders[i];
     698
     699        if (header.p_type != PT_LOAD)
     700            continue;
     701
     702        elf_region *region;
     703        if (header.IsReadWrite())
     704            region = &image->data_region;
     705        else if (header.IsExecutable())
     706            region = &image->text_region;
     707        else
     708            continue;
     709
     710        TRACE(("load segment %d (%ld bytes)...\n", i, header.p_filesz));
     711
     712        length = read_pos(fd, header.p_offset,
     713            (void *)(region->start + (header.p_vaddr % B_PAGE_SIZE)),
     714            header.p_filesz);
     715        if (length < (ssize_t)header.p_filesz) {
     716            status = B_BAD_DATA;
     717            dprintf("error reading in seg %d\n", i);
     718            goto error2;
     719        }
     720
     721        // Clear anything above the file size (that may also contain the BSS
     722        // area)
     723
     724        uint32 offset = (header.p_vaddr % B_PAGE_SIZE) + header.p_filesz;
     725        if (offset < region->size)
     726            memset((void *)(region->start + offset), 0, region->size - offset);
     727    }
     728
     729    // offset dynamic section, and program entry addresses by the delta of the
     730    // regions
     731    image->dynamic_section.start += image->text_region.delta;
     732    image->elf_header.e_entry += image->text_region.delta;
     733
     734    image->num_debug_symbols = 0;
     735    image->debug_symbols = NULL;
     736    image->debug_string_table = NULL;
     737
     738    if (sLoadElfSymbols)
     739        load_elf64_symbol_table(fd, image);
     740
     741    free(programHeaders);
     742
     743    return B_OK;
     744
     745error2:
     746    if (image->text_region.start != 0)
     747        platform_free_region((void *)image->text_region.start, totalSize);
     748error1:
     749    free(programHeaders);
     750
     751    return status;
     752}
     753
    411754status_t
     755elf_load_image(int fd, preloaded_image *image)
     756{
     757    status_t status;
     758
     759    TRACE(("elf_load_image(fd = %d, image = %p)\n", fd, image));
     760
     761    struct Elf32_Ehdr &elfHeader = image->elf_header;
     762    struct Elf64_Ehdr &elfHeader64 = image->elf_header64;
     763
     764    ssize_t length = read_pos(fd, 0, &elfHeader, sizeof(Elf32_Ehdr));
     765    if (length < (ssize_t)sizeof(Elf32_Ehdr))
     766        return B_BAD_TYPE;
     767
     768    status = verify_elf_header(elfHeader);
     769    if (status < B_OK) {    //not elf32. Check if elf64.
     770        ssize_t length = read_pos(fd, 0, &elfHeader64, sizeof(Elf64_Ehdr));
     771        if (length < (ssize_t)sizeof(Elf64_Ehdr))
     772            return B_BAD_TYPE;
     773
     774        status = verify_elf64_header(elfHeader64);
     775        if (status < B_OK)
     776            return status;
     777
     778        image->elf_size = 64;
     779        return elf64_load_image(fd, image);
     780    }
     781
     782    image->elf_size = 32;
     783    return elf32_load_image(fd, image);
     784}
     785
     786
     787status_t
    412788elf_load_image(Directory *directory, const char *path)
    413789{
    414790    preloaded_image *image;
     
    458834
    459835
    460836status_t
    461 elf_relocate_image(struct preloaded_image *image)
     837elf32_relocate_image(struct preloaded_image *image)
    462838{
    463839    status_t status = elf_parse_dynamic_section(image);
    464840    if (status != B_OK)
     
    503879
    504880
    505881status_t
     882elf64_relocate_image(struct preloaded_image *image)
     883{
     884    status_t status = elf64_parse_dynamic_section(image);
     885    if (status != B_OK)
     886        return status;
     887
     888    // deal with the rels first
     889    if (image->rel64) {
     890        TRACE(("total %i relocs\n",
     891            image->rel_len / (int)sizeof(struct Elf64_Rel)));
     892
     893        status = boot_arch_elf64_relocate_rel(image, image->rel64, image->rel_len);
     894        if (status < B_OK)
     895            return status;
     896    }
     897
     898    if (image->pltrel64) {
     899        TRACE(("total %i plt-relocs\n",
     900            image->pltrel_len / (int)sizeof(struct Elf64_Rel)));
     901
     902        if (image->pltrel_type == DT_REL) {
     903            status = boot_arch_elf64_relocate_rel(image, image->pltrel64,
     904                image->pltrel_len);
     905        } else {
     906            status = boot_arch_elf64_relocate_rela(image,
     907                (struct Elf64_Rela *)image->pltrel64, image->pltrel_len);
     908        }
     909        if (status < B_OK)
     910            return status;
     911    }
     912
     913    if (image->rela64) {
     914        TRACE(("total %i rela relocs\n",
     915            image->rela_len / (int)sizeof(struct Elf64_Rela)));
     916        status = boot_arch_elf64_relocate_rela(image, image->rela64,
     917            image->rela_len);
     918        if (status < B_OK)
     919            return status;
     920    }
     921    panic("relocate 4");
     922    return B_OK;
     923}
     924
     925status_t
     926elf_relocate_image(struct preloaded_image *image)
     927{
     928    if(image->elf_size == 32)
     929        return elf32_relocate_image(image);
     930
     931    return elf64_relocate_image(image);
     932}
     933
     934
     935status_t
    506936boot_elf_resolve_symbol(struct preloaded_image *image,
    507937    struct Elf32_Sym *symbol, addr_t *symbolAddress)
    508938{
     
    524954            return B_NO_ERROR;
    525955    }
    526956}
     957
     958status_t
     959boot_elf64_resolve_symbol(struct preloaded_image *image,
     960    struct Elf64_Sym *symbol, addr_t *symbolAddress)
     961{
     962    switch (symbol->st_shndx) {
     963        case SHN_UNDEF:
     964            // Since we do that only for the kernel, there shouldn't be
     965            // undefined symbols.
     966            return B_MISSING_SYMBOL;
     967        case SHN_ABS:
     968            *symbolAddress = symbol->st_value;
     969            return B_NO_ERROR;
     970        case SHN_COMMON:
     971            // ToDo: finish this
     972            TRACE(("elf_resolve_symbol: COMMON symbol, finish me!\n"));
     973            return B_ERROR;
     974        default:
     975            // standard symbol
     976            *symbolAddress = symbol->st_value + image->text_region.delta;
     977            return B_NO_ERROR;
     978    }
     979}
  • headers/private/system/elf32.h

     
    11/*
    2  * Copyright 2002-2009, Haiku Inc. All Rights Reserved.
     2 * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
    33 * Distributed under the terms of the MIT license.
    44 *
    55 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
     
    88#ifndef _ELF32_H
    99#define _ELF32_H
    1010
    11 
    1211#include <SupportDefs.h>
    1312#include <ByteOrder.h>
    1413
    1514#include <arch_elf.h>
     15#include <elf_common.h>
    1616
    17 
    1817typedef uint32 Elf32_Addr;
    1918typedef uint16 Elf32_Half;
    2019typedef uint32 Elf32_Off;
     
    2524
    2625/*** ELF header ***/
    2726
    28 #define EI_NIDENT   16
    29 
    3027struct Elf32_Ehdr {
    3128    uint8       e_ident[EI_NIDENT];
    3229    Elf32_Half  e_type;
     
    4845#endif
    4946};
    5047
    51 #define ELF_MAGIC   "\x7f""ELF"
    52 
    53 // e_ident[] indices
    54 #define EI_MAG0     0
    55 #define EI_MAG1     1
    56 #define EI_MAG2     2
    57 #define EI_MAG3     3
    58 #define EI_CLASS    4
    59 #define EI_DATA     5
    60 #define EI_VERSION  6
    61 #define EI_PAD      7
    62 
    63 // architecture class (EI_CLASS)
    64 #define ELFCLASS32  1
    65 #define ELFCLASS64  2
    66 // endian (EI_DATA)
    67 #define ELFDATA2LSB 1   /* little endian */
    68 #define ELFDATA2MSB 2   /* big endian */
    69 
    70 
    7148/*** section header ***/
    7249
    7350struct Elf32_Shdr {
     
    8360    Elf32_Word  sh_entsize;
    8461};
    8562
    86 // special section indices
    87 #define SHN_UNDEF       0
    88 #define SHN_LORESERVE   0xff00
    89 #define SHN_LOPROC      0xff00
    90 #define SHN_HIPROC      0xff1f
    91 #define SHN_ABS         0xfff1
    92 #define SHN_COMMON      0xfff2
    93 #define SHN_HIRESERVE   0xffff
    9463
    95 // section header type
    96 #define SHT_NULL        0
    97 #define SHT_PROGBITS    1
    98 #define SHT_SYMTAB      2
    99 #define SHT_STRTAB      3
    100 #define SHT_RELA        4
    101 #define SHT_HASH        5
    102 #define SHT_DYNAMIC     6
    103 #define SHT_NOTE        7
    104 #define SHT_NOBITS      8
    105 #define SHT_REL         9
    106 #define SHT_SHLIB       10
    107 #define SHT_DYNSYM      11
    108 
    109 #define SHT_GNU_verdef  0x6ffffffd    /* version definition section */
    110 #define SHT_GNU_verneed 0x6ffffffe    /* version needs section */
    111 #define SHT_GNU_versym  0x6fffffff    /* version symbol table */
    112 
    113 #define SHT_LOPROC      0x70000000
    114 #define SHT_HIPROC      0x7fffffff
    115 #define SHT_LOUSER      0x80000000
    116 #define SHT_HIUSER      0xffffffff
    117 
    118 // section header flags
    119 #define SHF_WRITE       1
    120 #define SHF_ALLOC       2
    121 #define SHF_EXECINSTR   4
    122 
    123 #define SHF_MASKPROC    0xf0000000
    124 
    125 
    12664/*** program header ***/
    12765
    12866struct Elf32_Phdr {
     
    14179#endif
    14280};
    14381
    144 // program header segment types
    145 #define PT_NULL     0
    146 #define PT_LOAD     1
    147 #define PT_DYNAMIC  2
    148 #define PT_INTERP   3
    149 #define PT_NOTE     4
    150 #define PT_SHLIB    5
    151 #define PT_PHDR     6
    152 #define PT_STACK    0x6474e551
    153 
    154 #define PT_LOPROC   0x70000000
    155 #define PT_HIPROC   0x7fffffff
    156 
    157 // program header segment flags
    158 #define PF_EXECUTE  0x1
    159 #define PF_WRITE    0x2
    160 #define PF_READ     0x4
    161 #define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ)
    162 
    163 #define PF_MASKPROC 0xf0000000
    164 
    16582struct Elf32_Sym {
    16683    Elf32_Word  st_name;
    16784    Elf32_Addr  st_value;
     
    18097#define ELF32_ST_TYPE(i) ((i) & 0xf)
    18198#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0xf))
    18299
    183 #define STT_NOTYPE 0
    184 #define STT_OBJECT 1
    185 #define STT_FUNC 2
    186 #define STT_SECTION 3
    187 #define STT_FILE 4
    188 #define STT_LOPROC 13
    189 #define STT_HIPROC 15
    190 
    191 #define STB_LOCAL 0
    192 #define STB_GLOBAL 1
    193 #define STB_WEAK 2
    194 #define STB_LOPROC 13
    195 #define STB_HIPROC 15
    196 
    197 #define STN_UNDEF 0
    198 
    199100struct Elf32_Rel {
    200101    Elf32_Addr r_offset;
    201102    Elf32_Word r_info;
     
    228129    } d_un;
    229130};
    230131
    231 #define DT_NULL     0
    232 #define DT_NEEDED   1
    233 #define DT_PLTRELSZ 2
    234 #define DT_PLTGOT   3
    235 #define DT_HASH     4
    236 #define DT_STRTAB   5
    237 #define DT_SYMTAB   6
    238 #define DT_RELA     7
    239 #define DT_RELASZ   8
    240 #define DT_RELAENT  9
    241 #define DT_STRSZ    10
    242 #define DT_SYMENT   11
    243 #define DT_INIT     12
    244 #define DT_FINI     13
    245 #define DT_SONAME   14
    246 #define DT_RPATH    15
    247 #define DT_SYMBOLIC 16
    248 #define DT_REL      17
    249 #define DT_RELSZ    18
    250 #define DT_RELENT   19
    251 #define DT_PLTREL   20
    252 #define DT_DEBUG    21
    253 #define DT_TEXTREL  22
    254 #define DT_JMPREL   23
    255 
    256 #define DT_VERSYM       0x6ffffff0  /* symbol version table */
    257 #define DT_VERDEF       0x6ffffffc  /* version definition table */
    258 #define DT_VERDEFNUM    0x6ffffffd  /* number of version definitions */
    259 #define DT_VERNEED      0x6ffffffe  /* table with needed versions */
    260 #define DT_VERNEEDNUM   0x6fffffff  /* number of needed versions */
    261 
    262 #define DT_LOPROC       0x70000000
    263 #define DT_HIPROC       0x7fffffff
    264 
    265 
    266132/* version definition section */
    267133
    268134struct Elf32_Verdef {
     
    276142    Elf32_Word  vd_next;        /* byte offset to next verdef entry */
    277143};
    278144
    279 /* values for vd_version (version revision) */
    280 #define VER_DEF_NONE        0       /* no version */
    281 #define VER_DEF_CURRENT     1       /* current version */
    282 #define VER_DEF_NUM         2       /* given version number */
    283 
    284 /* values for vd_flags (version information flags) */
    285 #define VER_FLG_BASE        0x1     /* version definition of file itself */
    286 #define VER_FLG_WEAK        0x2     /* weak version identifier */
    287 
    288 /* values for versym symbol index */
    289 #define VER_NDX_LOCAL       0       /* symbol is local */
    290 #define VER_NDX_GLOBAL      1       /* symbol is global/unversioned */
    291 #define VER_NDX_INITIAL     2       /* initial version -- that's the one given
    292                                        to symbols when a library becomes
    293                                        versioned; handled by the linker (and
    294                                        runtime loader) similar to
    295                                        VER_NDX_GLOBAL */
    296 #define VER_NDX_LORESERVE   0xff00  /* beginning of reserved entries */
    297 #define VER_NDX_ELIMINATE   0xff01  /* symbol is to be eliminated */
    298 
    299 #define VER_NDX_FLAG_HIDDEN 0x8000  /* flag: version is hidden */
    300 #define VER_NDX_MASK        0x7fff  /* mask to get the actual version index */
    301 #define VER_NDX(x)          ((x) & VER_NDX_MASK)
    302 
    303 
    304145/* auxiliary version information */
    305146
    306147struct Elf32_Verdaux {
     
    321162    Elf32_Word  vn_next;        /* byte offset to next verneed entry */
    322163};
    323164
    324 /* values for vn_version (version revision) */
    325 #define VER_NEED_NONE       0   /* no version */
    326 #define VER_NEED_CURRENT    1   /* current version */
    327 #define VER_NEED_NUM        2   /* given version number */
    328 
    329 
    330165/* auxiliary needed version information */
    331166
    332167struct Elf32_Vernaux {
     
    338173    Elf32_Word  vna_next;       /* byte offset to next vernaux entry */
    339174};
    340175
    341 /* values for vna_flags */
    342 #define VER_FLG_WEAK    0x2     /* weak version identifier */
    343 
    344 
    345176/*** inline functions ***/
    346177
    347178#ifdef __cplusplus
  • headers/private/system/elf_common.h

     
     1/*
     2 * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
     3 * Distributed under the terms of the MIT license.
     4 *
     5 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
     6 * Distributed under the terms of the NewOS License.
     7 */
     8#ifndef _ELF_COMMON_H
     9#define _ELF_COMMON_H
     10
     11#define EI_NIDENT   16
     12#define ELF_MAGIC   "\x7f""ELF"
     13
     14// e_ident[] indices
     15#define EI_MAG0     0
     16#define EI_MAG1     1
     17#define EI_MAG2     2
     18#define EI_MAG3     3
     19#define EI_CLASS    4
     20#define EI_DATA     5
     21#define EI_VERSION  6
     22#define EI_OSABI    7
     23#define EI_ABIVERSION   8
     24#define EI_PAD      9
     25
     26// architecture class (EI_CLASS)
     27#define ELFCLASS32  1
     28#define ELFCLASS64  2
     29// endian (EI_DATA)
     30#define ELFDATA2LSB 1   /* little endian */
     31#define ELFDATA2MSB 2   /* big endian */
     32
     33
     34// special section indices
     35#define SHN_LORESERVE       0xff00
     36#define SHN_HIRESERVE       0xffff
     37
     38#define SHN_UNDEF       0
     39#define SHN_LOPROC      0xff00
     40#define SHN_HIPROC      0xff1f
     41#define SHN_LODS        0xff20
     42#define SHN_HIOS        0xff3f
     43#define SHN_ABS         0xfff1
     44#define SHN_COMMON      0xfff2
     45
     46// section header type
     47#define SHT_NULL        0
     48#define SHT_PROGBITS        1
     49#define SHT_SYMTAB      2
     50#define SHT_STRTAB      3
     51#define SHT_RELA        4
     52#define SHT_HASH        5
     53#define SHT_DYNAMIC     6
     54#define SHT_NOTE        7
     55#define SHT_NOBITS      8
     56#define SHT_REL         9
     57#define SHT_SHLIB       10
     58#define SHT_DYNSYM      11
     59
     60#define SHT_GNU_verdef  0x6ffffffd    /* version definition section */
     61#define SHT_GNU_verneed 0x6ffffffe    /* version needs section */
     62#define SHT_GNU_versym  0x6fffffff    /* version symbol table */
     63
     64#define SHT_LODS        0x60000000
     65#define SHT_HIOS        0x6fffffff
     66#define SHT_LOPROC      0x70000000
     67#define SHT_HIPROC      0x7fffffff
     68#define SHT_LOUSER      0x80000000
     69#define SHT_HIUSER      0xffffffff
     70
     71// section header flags
     72#define SHF_WRITE       1
     73#define SHF_ALLOC       2
     74#define SHF_EXECINSTR       4
     75
     76#define SHF_MASKOS  0x0f000000
     77#define SHF_MASKPROC    0xf0000000
     78
     79// program header segment types
     80#define PT_NULL     0
     81#define PT_LOAD     1
     82#define PT_DYNAMIC  2
     83#define PT_INTERP   3
     84#define PT_NOTE     4
     85#define PT_SHLIB    5
     86#define PT_PHDR     6
     87#define PT_STACK    0x6474e551
     88
     89#define PT_LOOS     0x60000000
     90#define PT_HIOS     0x6fffffff
     91#define PT_LOPROC   0x70000000
     92#define PT_HIPROC   0x7fffffff
     93
     94// program header segment flags
     95#define PF_EXECUTE  0x1
     96#define PF_WRITE    0x2
     97#define PF_READ     0x4
     98#define PF_PROTECTION_MASK (PF_EXECUTE | PF_WRITE | PF_READ)
     99
     100#define PF_MASKOS   0x00ff0000
     101#define PF_MASKPROC 0xff000000
     102
     103#define STT_NOTYPE  0
     104#define STT_OBJECT  1
     105#define STT_FUNC    2
     106#define STT_SECTION 3
     107#define STT_FILE    4
     108#define STT_LOOS    10
     109#define STT_HIOS    12
     110#define STT_LOPROC  13
     111#define STT_HIPROC  15
     112
     113#define STB_LOCAL   0
     114#define STB_GLOBAL  1
     115#define STB_WEAK    2
     116#define STB_LOOS    10
     117#define STB_HIOS    11
     118#define STB_LOPROC  13
     119#define STB_HIPROC  15
     120
     121#define STN_UNDEF   0
     122
     123#define DT_NULL     0
     124#define DT_NEEDED   1
     125#define DT_PLTRELSZ 2
     126#define DT_PLTGOT   3
     127#define DT_HASH     4
     128#define DT_STRTAB   5
     129#define DT_SYMTAB   6
     130#define DT_RELA     7
     131#define DT_RELASZ   8
     132#define DT_RELAENT  9
     133#define DT_STRSZ    10
     134#define DT_SYMENT   11
     135#define DT_INIT     12
     136#define DT_FINI     13
     137#define DT_SONAME   14
     138#define DT_RPATH    15
     139#define DT_SYMBOLIC 16
     140#define DT_REL      17
     141#define DT_RELSZ    18
     142#define DT_RELENT   19
     143#define DT_PLTREL   20
     144#define DT_DEBUG    21
     145#define DT_TEXTREL  22
     146#define DT_JMPREL   23
     147#define DT_BIND_NOW 24
     148#define DT_INIT_ARRAY   25
     149#define DT_FINI_ARRAY   26
     150#define DT_INIT_ARRAYSZ 27
     151#define DT_FINI_ARRAYSZ 28
     152
     153
     154#define DT_VERSYM       0x6ffffff0  /* symbol version table */
     155#define DT_VERDEF       0x6ffffffc  /* version definition table */
     156#define DT_VERDEFNUM    0x6ffffffd  /* number of version definitions */
     157#define DT_VERNEED      0x6ffffffe  /* table with needed versions */
     158#define DT_VERNEEDNUM   0x6fffffff  /* number of needed versions */
     159
     160#define DT_LOPROC       0x70000000
     161#define DT_HIPROC       0x7fffffff
     162
     163
     164/* values for vd_version (version revision) */
     165#define VER_DEF_NONE        0       /* no version */
     166#define VER_DEF_CURRENT     1       /* current version */
     167#define VER_DEF_NUM         2       /* given version number */
     168
     169/* values for vd_flags (version information flags) */
     170#define VER_FLG_BASE        0x1     /* version definition of file itself */
     171#define VER_FLG_WEAK        0x2     /* weak version identifier */
     172
     173/* values for versym symbol index */
     174#define VER_NDX_LOCAL       0       /* symbol is local */
     175#define VER_NDX_GLOBAL      1       /* symbol is global/unversioned */
     176#define VER_NDX_INITIAL     2       /* initial version -- that's the one given
     177                                       to symbols when a library becomes
     178                                       versioned; handled by the linker (and
     179                                       runtime loader) similar to
     180                                       VER_NDX_GLOBAL */
     181#define VER_NDX_LORESERVE   0xff00  /* beginning of reserved entries */
     182#define VER_NDX_ELIMINATE   0xff01  /* symbol is to be eliminated */
     183
     184#define VER_NDX_FLAG_HIDDEN 0x8000  /* flag: version is hidden */
     185#define VER_NDX_MASK        0x7fff  /* mask to get the actual version index */
     186#define VER_NDX(x)          ((x) & VER_NDX_MASK)
     187
     188/* values for vn_version (version revision) */
     189#define VER_NEED_NONE       0   /* no version */
     190#define VER_NEED_CURRENT    1   /* current version */
     191#define VER_NEED_NUM        2   /* given version number */
     192
     193/* values for vna_flags */
     194#define VER_FLG_WEAK    0x2     /* weak version identifier */
     195
     196
     197#endif  /* _ELF_COMMON_H */
  • headers/private/system/elf64.h

     
     1/*
     2 * Copyright 2002-2010, Haiku Inc. All Rights Reserved.
     3 * Distributed under the terms of the MIT license.
     4 *
     5 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
     6 * Distributed under the terms of the NewOS License.
     7 */
     8#ifndef _ELF64_H
     9#define _ELF64_H
     10
     11#include <SupportDefs.h>
     12#include <ByteOrder.h>
     13
     14#include <arch_elf.h>
     15#include <elf_common.h>
     16
     17typedef uint64 Elf64_Addr;
     18typedef uint16 Elf64_Half;
     19typedef uint64 Elf64_Off;
     20typedef int32 Elf64_Sword;
     21typedef uint32 Elf64_Word;
     22typedef int64 Elf64_Sxword;
     23typedef uint64 Elf64_Xword;
     24
     25typedef Elf64_Half Elf64_Versym;
     26
     27/*** ELF header ***/
     28
     29struct Elf64_Ehdr {
     30    uint8       e_ident[EI_NIDENT];
     31    Elf64_Half  e_type;
     32    Elf64_Half  e_machine;
     33    Elf64_Word  e_version;
     34    Elf64_Addr  e_entry;
     35    Elf64_Off   e_phoff;
     36    Elf64_Off   e_shoff;
     37    Elf64_Word  e_flags;
     38    Elf64_Half  e_ehsize;
     39    Elf64_Half  e_phentsize;
     40    Elf64_Half  e_phnum;
     41    Elf64_Half  e_shentsize;
     42    Elf64_Half  e_shnum;
     43    Elf64_Half  e_shstrndx;
     44
     45#ifdef __cplusplus
     46    bool IsHostEndian() const;
     47#endif
     48};
     49
     50/*** section header ***/
     51
     52struct Elf64_Shdr {
     53    Elf64_Word  sh_name;
     54    Elf64_Word  sh_type;
     55    Elf64_Xword sh_flags;
     56    Elf64_Addr  sh_addr;
     57    Elf64_Off   sh_offset;
     58    Elf64_Xword sh_size;
     59    Elf64_Word  sh_link;
     60    Elf64_Word  sh_info;
     61    Elf64_Xword sh_addralign;
     62    Elf64_Xword sh_entsize;
     63};
     64
     65/*** program header ***/
     66
     67struct Elf64_Phdr {
     68    Elf64_Word  p_type;
     69    Elf64_Word  p_flags;
     70    Elf64_Off   p_offset;   /* offset from the beginning of the file of the segment */
     71    Elf64_Addr  p_vaddr;    /* virtual address for the segment in memory */
     72    Elf64_Addr  p_paddr;
     73    Elf64_Xword p_filesz;   /* the size of the segment in the file */
     74    Elf64_Xword p_memsz;    /* the size of the segment in memory */
     75    Elf64_Xword p_align;
     76
     77#ifdef __cplusplus
     78    bool IsReadWrite() const;
     79    bool IsExecutable() const;
     80#endif
     81};
     82
     83struct Elf64_Sym {
     84    Elf64_Word  st_name;
     85    uint8       st_info;
     86    uint8       st_other;
     87    Elf64_Half  st_shndx;
     88    Elf64_Addr  st_value;
     89    Elf64_Xword st_size;
     90
     91#ifdef __cplusplus
     92    uint8 Bind() const;
     93    uint8 Type() const;
     94#endif
     95};
     96
     97/* TODO: CHECK THESE DEFINES */
     98#define ELF64_ST_BIND(i) ((i) >> 8)
     99#define ELF64_ST_TYPE(i) ((i) & 0xffffffffL)
     100#define ELF64_ST_INFO(b, t) (((b) << 8) + ((t) & 0xffffffffL))
     101
     102struct Elf64_Rel {
     103    Elf64_Addr r_offset;
     104    Elf64_Xword r_info;
     105
     106#ifdef __cplusplus
     107    uint8 SymbolIndex() const;
     108    uint8 Type() const;
     109#endif
     110};
     111
     112#ifdef __cplusplus
     113struct Elf64_Rela : public Elf64_Rel {
     114#else
     115struct Elf64_Rela {
     116    Elf64_Addr r_offset;
     117    Elf64_Xword r_info;
     118#endif
     119    Elf64_Sxword r_addend;
     120};
     121
     122#define ELF64_R_SYM(i) ((i) >> 32)
     123#define ELF64_R_TYPE(i) ((i) & 0xffffffffL)
     124#define ELF64_R_INFO(s,t) (((s) << 32) + ((t) & 0xffffffffL))
     125
     126struct Elf64_Dyn {
     127    Elf64_Sxword d_tag;
     128    union {
     129        Elf64_Xword d_val;
     130        Elf64_Addr d_ptr;
     131    } d_un;
     132};
     133
     134/* version definition section */
     135/* TODO: ELF64 VERSION TABLES are guesses. Look up structure */
     136struct Elf64_Verdef {
     137    Elf64_Half  vd_version;     /* version revision */
     138    Elf64_Half  vd_flags;       /* version information flags */
     139    Elf64_Half  vd_ndx;         /* version index as specified in the
     140                                   symbol version table */
     141    Elf64_Half  vd_cnt;         /* number of associated verdaux entries */
     142    Elf64_Word  vd_hash;        /* version name hash value */
     143    Elf64_Xword vd_aux;         /* byte offset to verdaux array */
     144    Elf64_Xword vd_next;        /* byte offset to next verdef entry */
     145};
     146
     147/* auxiliary version information */
     148
     149struct Elf64_Verdaux {
     150    Elf64_Word  vda_name;       /* string table offset to version or dependency
     151                                   name */
     152    Elf64_Xword vda_next;       /* byte offset to next verdaux entry */
     153};
     154
     155/* version dependency section */
     156
     157struct Elf64_Verneed {
     158    Elf64_Half  vn_version;     /* version of structure */
     159    Elf64_Half  vn_cnt;         /* number of associated vernaux entries */
     160    Elf64_Xword vn_file;        /* byte offset to file name for this
     161                                   dependency */
     162    Elf64_Xword vn_aux;         /* byte offset to vernaux array */
     163    Elf64_Xword vn_next;        /* byte offset to next verneed entry */
     164};
     165
     166/* auxiliary needed version information */
     167
     168struct Elf64_Vernaux {
     169    Elf64_Word  vna_hash;       /* dependency name hash value */
     170    Elf64_Half  vna_flags;      /* dependency specific information flags */
     171    Elf64_Half  vna_other;      /* version index as specified in the symbol
     172                                   version table */
     173    Elf64_Xword vna_name;       /* string table offset to dependency name */
     174    Elf64_Xword vna_next;       /* byte offset to next vernaux entry */
     175};
     176
     177/*** inline functions ***/
     178
     179#ifdef __cplusplus
     180
     181inline bool
     182Elf64_Ehdr::IsHostEndian() const
     183{
     184#if B_HOST_IS_LENDIAN
     185    return e_ident[EI_DATA] == ELFDATA2LSB;
     186#elif B_HOST_IS_BENDIAN
     187    return e_ident[EI_DATA] == ELFDATA2MSB;
     188#endif
     189}
     190
     191
     192inline bool
     193Elf64_Phdr::IsReadWrite() const
     194{
     195    return !(~p_flags & (PF_READ | PF_WRITE));
     196}
     197
     198
     199inline bool
     200Elf64_Phdr::IsExecutable() const
     201{
     202    return (p_flags & PF_PROTECTION_MASK) == (PF_READ | PF_EXECUTE);
     203}
     204
     205
     206inline uint8
     207Elf64_Sym::Bind() const
     208{
     209    return ELF64_ST_BIND(st_info);
     210}
     211
     212
     213inline uint8
     214Elf64_Sym::Type() const
     215{
     216    return ELF64_ST_TYPE(st_info);
     217}
     218
     219
     220inline uint8
     221Elf64_Rel::SymbolIndex() const
     222{
     223    return ELF64_R_SYM(r_info);
     224}
     225
     226
     227inline uint8
     228Elf64_Rel::Type() const
     229{
     230    return ELF64_R_TYPE(r_info);
     231}
     232
     233#endif  /* __cplusplus */
     234
     235#endif  /* _ELF64_H_ */
  • headers/private/system/arch/x86/arch_elf.h

     
    1919#define R_386_GOTOFF    9   /* add GOT relative symbol address */
    2020#define R_386_GOTPC     10  /* add PC relative GOT table address */
    2121
     22#define R_X86_64_NONE       0
     23#define R_X86_64_64     1   /* add symbol value */
     24#define R_X86_64_PC32       2   /* add PC relative symbol value */
     25#define R_X86_64_GOT32      3   /* add PC relative GOT offset */
     26#define R_X86_64_PLT32      4   /* add PC relative PLT offset */
     27#define R_X86_64_COPY       5   /* copy data from shared object */
     28#define R_X86_64_GLOB_DAT   6   /* set GOT entry to data address */
     29#define R_X86_64_JMP_SLOT   7   /* set GOT entry to code address */
     30#define R_X86_64_RELATIVE   8   /* add load address of shared object */
     31#define R_X86_64_GOTOFF     9   /* add GOT relative symbol address */
     32#define R_X86_64_32     10      /* Add 32 bit zero extended symbol value */
     33#define R_X86_64_32S        11      /* Add 32 bit sign extended symbol value */
     34#define R_X86_64_16     12      /* Add 16 bit zero extended symbol value */
     35#define R_X86_64_PC16       13      /* Add 16 bit signed extended pc relative symbol value */
     36#define R_X86_64_8      14      /* Add 8 bit zero extended symbol value */
     37#define R_X86_64_PC8        15      /* Add 8 bit signed extended pc relative symbol value */
     38
     39
    2240#endif  /* _KERNEL_ARCH_x86_ELF_H */
  • headers/private/kernel/boot/addr_range.h

     
    66#ifndef KERNEL_BOOT_ADDR_RANGE_H
    77#define KERNEL_BOOT_ADDR_RANGE_H
    88
    9 
    109#include <SupportDefs.h>
    1110
     11#include <util/FixedWidthPointer.h>
    1212
    1313typedef struct addr_range {
    14     addr_t start;
    15     size_t size;
     14    FixedWidthPointer<addr_t> start;
     15    size_t  size;
    1616} addr_range;
    1717
    1818
    1919typedef struct phys_addr_range {
    20     phys_addr_t start;
     20    FixedWidthPointer<phys_addr_t> start;
    2121    phys_size_t size;
    2222} phys_addr_range;
    2323
    24 
    2524#ifdef __cplusplus
    2625extern "C" {
    2726#endif
  • headers/private/kernel/elf_priv.h

     
    1010
    1111
    1212#include <elf32.h>
     13#include <elf64.h>
    1314#include <image.h>
    1415
    1516
     
    6768#define STRING(image, offset) ((char *)(&(image)->strtab[(offset)]))
    6869#define SYMNAME(image, sym) STRING(image, (sym)->st_name)
    6970#define SYMBOL(image, num) ((struct Elf32_Sym *)&(image)->syms[num])
     71#define SYMBOL64(image, num) ((struct Elf64_Sym *)&(image)->syms[num])
    7072#define HASHTABSIZE(image) ((image)->symhash[0])
    7173#define HASHBUCKETS(image) ((unsigned int *)&(image)->symhash[2])
    7274#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
  • headers/private/kernel/util/FixedWidthPointer.h

     
     1/*
     2 * Distributed under the terms of the MIT License.
     3 */
     4#ifndef KERNEL_UTIL_FIXED_WIDTH_POINTER_H
     5#define KERNEL_UTIL_FIXED_WIDTH_POINTER_H
     6
     7#include <SupportDefs.h>
     8
     9#ifdef __cplusplus
     10template<typename Type>
     11class FixedWidthPointer {
     12public:
     13        operator Type() const
     14        {
     15                return (Type)(addr_t)fValue;
     16        }
     17        operator void*() const
     18        {
     19                return (void*)fValue;
     20        }
     21        Type* operator*() const
     22        {
     23                return *(Type)*this;
     24        }
     25        Type operator->() const
     26        {
     27                return *this;
     28        }
     29        FixedWidthPointer<Type> operator=(Type pointer)
     30        {
     31                fValue = (addr_t)pointer;
     32                return *this;
     33        }
     34        FixedWidthPointer<Type> operator+=(Type pointer)
     35        {
     36                fValue = fValue + (addr_t)pointer;
     37                return *this;
     38        }
     39        bool operator==(const Type pointer) const
     40        {
     41                return fValue == (addr_t)pointer;
     42        }
     43        bool operator>=(const Type pointer) const
     44        {
     45                return fValue >= (addr_t)pointer;
     46        }
     47        bool operator<(const Type pointer) const
     48        {
     49                return fValue < (addr_t)pointer;
     50        }
     51private:
     52        uint64  fValue;
     53};
     54#endif
     55
     56#endif  // _KERNEL_UTIL_FIXED_WIDTH_POINTER_H