Changed runtime_loader to use elf_* typedefs over Elf32_*.
This means that it will be using ELF64 types on x86_64 rather than ELF32. The next step for supporting x86_64 is to implement relocations.
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
#include <elf32.h>
|
#include <elf32.h>
|
||||||
|
#include <elf64.h>
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - runtime loader libroot interface
|
// #pragma mark - runtime loader libroot interface
|
||||||
@@ -100,13 +101,13 @@ typedef struct image_t {
|
|||||||
|
|
||||||
// pointer to symbol participation data structures
|
// pointer to symbol participation data structures
|
||||||
uint32 *symhash;
|
uint32 *symhash;
|
||||||
struct Elf32_Sym *syms;
|
elf_sym *syms;
|
||||||
char *strtab;
|
char *strtab;
|
||||||
struct Elf32_Rel *rel;
|
elf_rel *rel;
|
||||||
int rel_len;
|
int rel_len;
|
||||||
struct Elf32_Rela *rela;
|
elf_rela *rela;
|
||||||
int rela_len;
|
int rela_len;
|
||||||
struct Elf32_Rel *pltrel;
|
elf_rel *pltrel;
|
||||||
int pltrel_len;
|
int pltrel_len;
|
||||||
|
|
||||||
uint32 num_needed;
|
uint32 num_needed;
|
||||||
@@ -114,20 +115,20 @@ typedef struct image_t {
|
|||||||
|
|
||||||
// versioning related structures
|
// versioning related structures
|
||||||
uint32 num_version_definitions;
|
uint32 num_version_definitions;
|
||||||
struct Elf32_Verdef *version_definitions;
|
elf_verdef *version_definitions;
|
||||||
uint32 num_needed_versions;
|
uint32 num_needed_versions;
|
||||||
struct Elf32_Verneed *needed_versions;
|
elf_verneed *needed_versions;
|
||||||
Elf32_Versym *symbol_versions;
|
elf_versym *symbol_versions;
|
||||||
elf_version_info *versions;
|
elf_version_info *versions;
|
||||||
uint32 num_versions;
|
uint32 num_versions;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
struct Elf32_Sym* (*find_undefined_symbol)(struct image_t* rootImage,
|
elf_sym* (*find_undefined_symbol)(struct image_t* rootImage,
|
||||||
struct image_t* image,
|
struct image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo,
|
const SymbolLookupInfo& lookupInfo,
|
||||||
struct image_t** foundInImage);
|
struct image_t** foundInImage);
|
||||||
#else
|
#else
|
||||||
struct Elf32_Sym* (*find_undefined_symbol)(struct image_t* rootImage,
|
elf_sym* (*find_undefined_symbol)(struct image_t* rootImage,
|
||||||
struct image_t* image,
|
struct image_t* image,
|
||||||
const struct SymbolLookupInfo* lookupInfo,
|
const struct SymbolLookupInfo* lookupInfo,
|
||||||
struct image_t** foundInImage);
|
struct image_t** foundInImage);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
#include <elf32.h>
|
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
|
||||||
@@ -70,7 +69,7 @@ static const char *
|
|||||||
find_dt_rpath(image_t *image)
|
find_dt_rpath(image_t *image)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
|
elf_dyn *d = (elf_dyn *)image->dynamic_ptr;
|
||||||
|
|
||||||
for (i = 0; d[i].d_tag != DT_NULL; i++) {
|
for (i = 0; d[i].d_tag != DT_NULL; i++) {
|
||||||
if (d[i].d_tag == DT_RPATH)
|
if (d[i].d_tag == DT_RPATH)
|
||||||
@@ -84,7 +83,7 @@ find_dt_rpath(image_t *image)
|
|||||||
static status_t
|
static status_t
|
||||||
load_immediate_dependencies(image_t *image)
|
load_immediate_dependencies(image_t *image)
|
||||||
{
|
{
|
||||||
struct Elf32_Dyn *d = (struct Elf32_Dyn *)image->dynamic_ptr;
|
elf_dyn *d = (elf_dyn *)image->dynamic_ptr;
|
||||||
bool reportErrors = report_errors();
|
bool reportErrors = report_errors();
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
uint32 i, j;
|
uint32 i, j;
|
||||||
@@ -670,7 +669,7 @@ get_nth_symbol(image_id imageID, int32 num, char *nameBuffer,
|
|||||||
// iterate through all the hash buckets until we've found the one
|
// iterate through all the hash buckets until we've found the one
|
||||||
for (i = 0; i < HASHTABSIZE(image); i++) {
|
for (i = 0; i < HASHTABSIZE(image); i++) {
|
||||||
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
for (j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
|
||||||
struct Elf32_Sym *symbol = &image->syms[j];
|
elf_sym *symbol = &image->syms[j];
|
||||||
|
|
||||||
if (count == num) {
|
if (count == num) {
|
||||||
const char* symbolName = SYMNAME(image, symbol);
|
const char* symbolName = SYMNAME(image, symbol);
|
||||||
@@ -680,9 +679,9 @@ get_nth_symbol(image_id imageID, int32 num, char *nameBuffer,
|
|||||||
void* location = (void*)(symbol->st_value
|
void* location = (void*)(symbol->st_value
|
||||||
+ image->regions[0].delta);
|
+ image->regions[0].delta);
|
||||||
int32 type;
|
int32 type;
|
||||||
if (ELF32_ST_TYPE(symbol->st_info) == STT_FUNC)
|
if (symbol->Type() == STT_FUNC)
|
||||||
type = B_SYMBOL_TYPE_TEXT;
|
type = B_SYMBOL_TYPE_TEXT;
|
||||||
else if (ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT)
|
else if (symbol->Type() == STT_OBJECT)
|
||||||
type = B_SYMBOL_TYPE_DATA;
|
type = B_SYMBOL_TYPE_DATA;
|
||||||
else
|
else
|
||||||
type = B_SYMBOL_TYPE_ANY;
|
type = B_SYMBOL_TYPE_ANY;
|
||||||
@@ -721,14 +720,14 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Elf32_Sym* foundSymbol = NULL;
|
elf_sym* foundSymbol = NULL;
|
||||||
addr_t foundLocation = (addr_t)NULL;
|
addr_t foundLocation = (addr_t)NULL;
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (uint32 i = 0; i < HASHTABSIZE(image) && !found; i++) {
|
for (uint32 i = 0; i < HASHTABSIZE(image) && !found; i++) {
|
||||||
for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
|
for (int32 j = HASHBUCKETS(image)[i]; j != STN_UNDEF;
|
||||||
j = HASHCHAINS(image)[j]) {
|
j = HASHCHAINS(image)[j]) {
|
||||||
struct Elf32_Sym *symbol = &image->syms[j];
|
elf_sym *symbol = &image->syms[j];
|
||||||
addr_t location = symbol->st_value + image->regions[0].delta;
|
addr_t location = symbol->st_value + image->regions[0].delta;
|
||||||
|
|
||||||
if (location <= (addr_t)address && location >= foundLocation) {
|
if (location <= (addr_t)address && location >= foundLocation) {
|
||||||
@@ -753,9 +752,9 @@ get_nearest_symbol_at_address(void* address, image_id* _imageID,
|
|||||||
*_symbolName = SYMNAME(image, foundSymbol);
|
*_symbolName = SYMNAME(image, foundSymbol);
|
||||||
|
|
||||||
if (_type != NULL) {
|
if (_type != NULL) {
|
||||||
if (ELF32_ST_TYPE(foundSymbol->st_info) == STT_FUNC)
|
if (foundSymbol->Type() == STT_FUNC)
|
||||||
*_type = B_SYMBOL_TYPE_TEXT;
|
*_type = B_SYMBOL_TYPE_TEXT;
|
||||||
else if (ELF32_ST_TYPE(foundSymbol->st_info) == STT_OBJECT)
|
else if (foundSymbol->Type() == STT_OBJECT)
|
||||||
*_type = B_SYMBOL_TYPE_DATA;
|
*_type = B_SYMBOL_TYPE_DATA;
|
||||||
else
|
else
|
||||||
*_type = B_SYMBOL_TYPE_ANY;
|
*_type = B_SYMBOL_TYPE_ANY;
|
||||||
@@ -831,14 +830,14 @@ get_library_symbol(void* handle, void* caller, const char* symbolName,
|
|||||||
if (handle == RTLD_DEFAULT || handle == RLD_GLOBAL_SCOPE) {
|
if (handle == RTLD_DEFAULT || handle == RLD_GLOBAL_SCOPE) {
|
||||||
// look in the default scope
|
// look in the default scope
|
||||||
image_t* image;
|
image_t* image;
|
||||||
Elf32_Sym* symbol = find_undefined_symbol_global(gProgramImage,
|
elf_sym* symbol = find_undefined_symbol_global(gProgramImage,
|
||||||
gProgramImage,
|
gProgramImage,
|
||||||
SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_ANY, NULL,
|
SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_ANY, NULL,
|
||||||
LOOKUP_FLAG_DEFAULT_VERSION),
|
LOOKUP_FLAG_DEFAULT_VERSION),
|
||||||
&image);
|
&image);
|
||||||
if (symbol != NULL) {
|
if (symbol != NULL) {
|
||||||
*_location = (void*)(symbol->st_value + image->regions[0].delta);
|
*_location = (void*)(symbol->st_value + image->regions[0].delta);
|
||||||
int32 symbolType = ELF32_ST_TYPE(symbol->st_info) == STT_FUNC
|
int32 symbolType = symbol->Type() == STT_FUNC
|
||||||
? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
|
? B_SYMBOL_TYPE_TEXT : B_SYMBOL_TYPE_DATA;
|
||||||
patch_defined_symbol(image, symbolName, _location, &symbolType);
|
patch_defined_symbol(image, symbolName, _location, &symbolType);
|
||||||
status = B_OK;
|
status = B_OK;
|
||||||
@@ -864,7 +863,7 @@ get_library_symbol(void* handle, void* caller, const char* symbolName,
|
|||||||
bool hitCallerImage = false;
|
bool hitCallerImage = false;
|
||||||
set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
|
set_image_flags_recursively(callerImage, RFLAG_USE_FOR_RESOLVING);
|
||||||
|
|
||||||
Elf32_Sym* candidateSymbol = NULL;
|
elf_sym* candidateSymbol = NULL;
|
||||||
image_t* candidateImage = NULL;
|
image_t* candidateImage = NULL;
|
||||||
|
|
||||||
image_t* image = get_loaded_images().head;
|
image_t* image = get_loaded_images().head;
|
||||||
@@ -883,14 +882,14 @@ get_library_symbol(void* handle, void* caller, const char* symbolName,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Elf32_Sym *symbol = find_symbol(image,
|
elf_sym *symbol = find_symbol(image,
|
||||||
SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_TEXT, NULL,
|
SymbolLookupInfo(symbolName, B_SYMBOL_TYPE_TEXT, NULL,
|
||||||
LOOKUP_FLAG_DEFAULT_VERSION));
|
LOOKUP_FLAG_DEFAULT_VERSION));
|
||||||
if (symbol == NULL)
|
if (symbol == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// found a symbol
|
// found a symbol
|
||||||
bool isWeak = ELF32_ST_BIND(symbol->st_info) == STB_WEAK;
|
bool isWeak = symbol->Bind() == STB_WEAK;
|
||||||
if (candidateImage == NULL || !isWeak) {
|
if (candidateImage == NULL || !isWeak) {
|
||||||
candidateSymbol = symbol;
|
candidateSymbol = symbol;
|
||||||
candidateImage = image;
|
candidateImage = image;
|
||||||
@@ -932,7 +931,7 @@ status_t
|
|||||||
get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
|
get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
|
||||||
{
|
{
|
||||||
uint32 i, j, searchIndex = *cookie;
|
uint32 i, j, searchIndex = *cookie;
|
||||||
struct Elf32_Dyn *dynamicSection;
|
elf_dyn *dynamicSection;
|
||||||
image_t *image;
|
image_t *image;
|
||||||
|
|
||||||
if (_name == NULL)
|
if (_name == NULL)
|
||||||
@@ -946,7 +945,7 @@ get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
|
|||||||
return B_BAD_IMAGE_ID;
|
return B_BAD_IMAGE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamicSection = (struct Elf32_Dyn *)image->dynamic_ptr;
|
dynamicSection = (elf_dyn *)image->dynamic_ptr;
|
||||||
if (dynamicSection == NULL || image->num_needed <= searchIndex) {
|
if (dynamicSection == NULL || image->num_needed <= searchIndex) {
|
||||||
rld_unlock();
|
rld_unlock();
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
@@ -976,15 +975,14 @@ get_next_image_dependency(image_id id, uint32 *cookie, const char **_name)
|
|||||||
|
|
||||||
/*! Read and verify the ELF header */
|
/*! Read and verify the ELF header */
|
||||||
status_t
|
status_t
|
||||||
elf_verify_header(void *header, int32 length)
|
elf_verify_header(void *header, size_t length)
|
||||||
{
|
{
|
||||||
int32 programSize, sectionSize;
|
int32 programSize, sectionSize;
|
||||||
|
|
||||||
if (length < (int32)sizeof(struct Elf32_Ehdr))
|
if (length < sizeof(elf_ehdr))
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
return parse_elf_header((struct Elf32_Ehdr *)header, &programSize,
|
return parse_elf_header((elf_ehdr *)header, &programSize, §ionSize);
|
||||||
§ionSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1029,7 +1027,7 @@ rldelf_init(void)
|
|||||||
|
|
||||||
// create the debug area
|
// create the debug area
|
||||||
{
|
{
|
||||||
int32 size = TO_PAGE_SIZE(sizeof(runtime_loader_debug_area));
|
size_t size = TO_PAGE_SIZE(sizeof(runtime_loader_debug_area));
|
||||||
|
|
||||||
runtime_loader_debug_area *area;
|
runtime_loader_debug_area *area;
|
||||||
area_id areaID = _kern_create_area(RUNTIME_LOADER_DEBUG_AREA_NAME,
|
area_id areaID = _kern_create_area(RUNTIME_LOADER_DEBUG_AREA_NAME,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader,
|
analyze_object_gcc_version(int fd, image_t* image, elf_ehdr& eheader,
|
||||||
int32 sheaderSize, char* buffer, size_t bufferSize)
|
int32 sheaderSize, char* buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
if (sheaderSize > (int)bufferSize) {
|
if (sheaderSize > (int)bufferSize) {
|
||||||
@@ -38,8 +38,8 @@ analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load the string section
|
// load the string section
|
||||||
Elf32_Shdr* sectionHeader
|
elf_shdr* sectionHeader
|
||||||
= (Elf32_Shdr*)(buffer + eheader.e_shstrndx * eheader.e_shentsize);
|
= (elf_shdr*)(buffer + eheader.e_shstrndx * eheader.e_shentsize);
|
||||||
|
|
||||||
if (sheaderSize + sectionHeader->sh_size > bufferSize) {
|
if (sheaderSize + sectionHeader->sh_size > bufferSize) {
|
||||||
FATAL("%s: Buffer not big enough for section string section\n",
|
FATAL("%s: Buffer not big enough for section string section\n",
|
||||||
@@ -60,7 +60,7 @@ analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader,
|
|||||||
off_t commentOffset = 0;
|
off_t commentOffset = 0;
|
||||||
size_t commentSize = 0;
|
size_t commentSize = 0;
|
||||||
for (uint32 i = 0; i < eheader.e_shnum; i++) {
|
for (uint32 i = 0; i < eheader.e_shnum; i++) {
|
||||||
sectionHeader = (Elf32_Shdr*)(buffer + i * eheader.e_shentsize);
|
sectionHeader = (elf_shdr*)(buffer + i * eheader.e_shentsize);
|
||||||
const char* sectionName = sectionStrings + sectionHeader->sh_name;
|
const char* sectionName = sectionStrings + sectionHeader->sh_name;
|
||||||
if (sectionHeader->sh_name != 0
|
if (sectionHeader->sh_name != 0
|
||||||
&& strcmp(sectionName, ".comment") == 0) {
|
&& strcmp(sectionName, ".comment") == 0) {
|
||||||
@@ -189,16 +189,16 @@ analyze_object_gcc_version(int fd, image_t* image, Elf32_Ehdr& eheader,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
analyze_image_haiku_version_and_abi(int fd, image_t* image, Elf32_Ehdr& eheader,
|
analyze_image_haiku_version_and_abi(int fd, image_t* image, elf_ehdr& eheader,
|
||||||
int32 sheaderSize, char* buffer, size_t bufferSize)
|
int32 sheaderSize, char* buffer, size_t bufferSize)
|
||||||
{
|
{
|
||||||
// Haiku API version
|
// Haiku API version
|
||||||
struct Elf32_Sym* symbol = find_symbol(image,
|
elf_sym* symbol = find_symbol(image,
|
||||||
SymbolLookupInfo(B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME,
|
SymbolLookupInfo(B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME,
|
||||||
B_SYMBOL_TYPE_DATA));
|
B_SYMBOL_TYPE_DATA));
|
||||||
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
||||||
&& symbol->st_value > 0
|
&& symbol->st_value > 0
|
||||||
&& ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT
|
&& symbol->Type() == STT_OBJECT
|
||||||
&& symbol->st_size >= sizeof(uint32)) {
|
&& symbol->st_size >= sizeof(uint32)) {
|
||||||
image->api_version
|
image->api_version
|
||||||
= *(uint32*)(symbol->st_value + image->regions[0].delta);
|
= *(uint32*)(symbol->st_value + image->regions[0].delta);
|
||||||
@@ -211,7 +211,7 @@ analyze_image_haiku_version_and_abi(int fd, image_t* image, Elf32_Ehdr& eheader,
|
|||||||
B_SYMBOL_TYPE_DATA));
|
B_SYMBOL_TYPE_DATA));
|
||||||
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
|
||||||
&& symbol->st_value > 0
|
&& symbol->st_value > 0
|
||||||
&& ELF32_ST_TYPE(symbol->st_info) == STT_OBJECT
|
&& symbol->Type() == STT_OBJECT
|
||||||
&& symbol->st_size >= sizeof(uint32)) {
|
&& symbol->st_size >= sizeof(uint32)) {
|
||||||
image->abi = *(uint32*)(symbol->st_value + image->regions[0].delta);
|
image->abi = *(uint32*)(symbol->st_value + image->regions[0].delta);
|
||||||
} else
|
} else
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
|
|
||||||
void analyze_image_haiku_version_and_abi(int fd, image_t* image,
|
void analyze_image_haiku_version_and_abi(int fd, image_t* image,
|
||||||
Elf32_Ehdr& eheader, int32 sheaderSize, char* buffer,
|
elf_ehdr& eheader, int32 sheaderSize, char* buffer,
|
||||||
size_t bufferSize);
|
size_t bufferSize);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ get_program_path()
|
|||||||
static int32
|
static int32
|
||||||
count_regions(const char* imagePath, char const* buff, int phnum, int phentsize)
|
count_regions(const char* imagePath, char const* buff, int phnum, int phentsize)
|
||||||
{
|
{
|
||||||
struct Elf32_Phdr* pheaders;
|
elf_phdr* pheaders;
|
||||||
int32 count = 0;
|
int32 count = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < phnum; i++) {
|
for (i = 0; i < phnum; i++) {
|
||||||
pheaders = (struct Elf32_Phdr*)(buff + i * phentsize);
|
pheaders = (elf_phdr*)(buff + i * phentsize);
|
||||||
|
|
||||||
switch (pheaders->p_type) {
|
switch (pheaders->p_type) {
|
||||||
case PT_NULL:
|
case PT_NULL:
|
||||||
@@ -78,7 +78,7 @@ count_regions(const char* imagePath, char const* buff, int phnum, int phentsize)
|
|||||||
// we don't use it
|
// we don't use it
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FATAL("%s: Unhandled pheader type in count 0x%lx\n",
|
FATAL("%s: Unhandled pheader type in count 0x%" B_PRIx32 "\n",
|
||||||
imagePath, pheaders->p_type);
|
imagePath, pheaders->p_type);
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
@@ -91,13 +91,13 @@ count_regions(const char* imagePath, char const* buff, int phnum, int phentsize)
|
|||||||
static status_t
|
static status_t
|
||||||
parse_program_headers(image_t* image, char* buff, int phnum, int phentsize)
|
parse_program_headers(image_t* image, char* buff, int phnum, int phentsize)
|
||||||
{
|
{
|
||||||
struct Elf32_Phdr* pheader;
|
elf_phdr* pheader;
|
||||||
int regcount;
|
int regcount;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
regcount = 0;
|
regcount = 0;
|
||||||
for (i = 0; i < phnum; i++) {
|
for (i = 0; i < phnum; i++) {
|
||||||
pheader = (struct Elf32_Phdr*)(buff + i * phentsize);
|
pheader = (elf_phdr*)(buff + i * phentsize);
|
||||||
|
|
||||||
switch (pheader->p_type) {
|
switch (pheader->p_type) {
|
||||||
case PT_NULL:
|
case PT_NULL:
|
||||||
@@ -194,7 +194,7 @@ parse_program_headers(image_t* image, char* buff, int phnum, int phentsize)
|
|||||||
// we don't use it
|
// we don't use it
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FATAL("%s: Unhandled pheader type in parse 0x%lx\n",
|
FATAL("%s: Unhandled pheader type in parse 0x%" B_PRIx32 "\n",
|
||||||
image->path, pheader->p_type);
|
image->path, pheader->p_type);
|
||||||
return B_BAD_DATA;
|
return B_BAD_DATA;
|
||||||
}
|
}
|
||||||
@@ -227,7 +227,7 @@ assert_dynamic_loadable(image_t* image)
|
|||||||
static bool
|
static bool
|
||||||
parse_dynamic_segment(image_t* image)
|
parse_dynamic_segment(image_t* image)
|
||||||
{
|
{
|
||||||
struct Elf32_Dyn* d;
|
elf_dyn* d;
|
||||||
int i;
|
int i;
|
||||||
int sonameOffset = -1;
|
int sonameOffset = -1;
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ parse_dynamic_segment(image_t* image)
|
|||||||
image->syms = 0;
|
image->syms = 0;
|
||||||
image->strtab = 0;
|
image->strtab = 0;
|
||||||
|
|
||||||
d = (struct Elf32_Dyn*)image->dynamic_ptr;
|
d = (elf_dyn*)image->dynamic_ptr;
|
||||||
if (!d)
|
if (!d)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -253,18 +253,18 @@ parse_dynamic_segment(image_t* image)
|
|||||||
= (char*)(d[i].d_un.d_ptr + image->regions[0].delta);
|
= (char*)(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_SYMTAB:
|
case DT_SYMTAB:
|
||||||
image->syms = (struct Elf32_Sym*)
|
image->syms = (elf_sym*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_REL:
|
case DT_REL:
|
||||||
image->rel = (struct Elf32_Rel*)
|
image->rel = (elf_rel*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_RELSZ:
|
case DT_RELSZ:
|
||||||
image->rel_len = d[i].d_un.d_val;
|
image->rel_len = d[i].d_un.d_val;
|
||||||
break;
|
break;
|
||||||
case DT_RELA:
|
case DT_RELA:
|
||||||
image->rela = (struct Elf32_Rela*)
|
image->rela = (elf_rela*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_RELASZ:
|
case DT_RELASZ:
|
||||||
@@ -272,7 +272,7 @@ parse_dynamic_segment(image_t* image)
|
|||||||
break;
|
break;
|
||||||
case DT_JMPREL:
|
case DT_JMPREL:
|
||||||
// procedure linkage table relocations
|
// procedure linkage table relocations
|
||||||
image->pltrel = (struct Elf32_Rel*)
|
image->pltrel = (elf_rel*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_PLTRELSZ:
|
case DT_PLTRELSZ:
|
||||||
@@ -290,18 +290,18 @@ parse_dynamic_segment(image_t* image)
|
|||||||
sonameOffset = d[i].d_un.d_val;
|
sonameOffset = d[i].d_un.d_val;
|
||||||
break;
|
break;
|
||||||
case DT_VERSYM:
|
case DT_VERSYM:
|
||||||
image->symbol_versions = (Elf32_Versym*)
|
image->symbol_versions = (elf_versym*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_VERDEF:
|
case DT_VERDEF:
|
||||||
image->version_definitions = (Elf32_Verdef*)
|
image->version_definitions = (elf_verdef*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_VERDEFNUM:
|
case DT_VERDEFNUM:
|
||||||
image->num_version_definitions = d[i].d_un.d_val;
|
image->num_version_definitions = d[i].d_un.d_val;
|
||||||
break;
|
break;
|
||||||
case DT_VERNEED:
|
case DT_VERNEED:
|
||||||
image->needed_versions = (Elf32_Verneed*)
|
image->needed_versions = (elf_verneed*)
|
||||||
(d[i].d_un.d_ptr + image->regions[0].delta);
|
(d[i].d_un.d_ptr + image->regions[0].delta);
|
||||||
break;
|
break;
|
||||||
case DT_VERNEEDNUM:
|
case DT_VERNEEDNUM:
|
||||||
@@ -350,19 +350,19 @@ parse_dynamic_segment(image_t* image)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
parse_elf_header(struct Elf32_Ehdr* eheader, int32* _pheaderSize,
|
parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize,
|
||||||
int32* _sheaderSize)
|
int32* _sheaderSize)
|
||||||
{
|
{
|
||||||
if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
|
if (memcmp(eheader->e_ident, ELF_MAGIC, 4) != 0)
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
if (eheader->e_ident[4] != ELFCLASS32)
|
if (eheader->e_ident[4] != ELF_CLASS)
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
if (eheader->e_phoff == 0)
|
if (eheader->e_phoff == 0)
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
if (eheader->e_phentsize < sizeof(struct Elf32_Phdr))
|
if (eheader->e_phentsize < sizeof(elf_phdr))
|
||||||
return B_NOT_AN_EXECUTABLE;
|
return B_NOT_AN_EXECUTABLE;
|
||||||
|
|
||||||
*_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
|
*_pheaderSize = eheader->e_phentsize * eheader->e_phnum;
|
||||||
@@ -389,7 +389,7 @@ load_image(char const* name, image_type type, const char* rpath,
|
|||||||
status_t status;
|
status_t status;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
struct Elf32_Ehdr eheader;
|
elf_ehdr eheader;
|
||||||
|
|
||||||
// Have we already loaded that image? Don't check for add-ons -- we always
|
// Have we already loaded that image? Don't check for add-ons -- we always
|
||||||
// reload them.
|
// reload them.
|
||||||
@@ -480,8 +480,8 @@ load_image(char const* name, image_type type, const char* rpath,
|
|||||||
numRegions = count_regions(path, pheaderBuffer, eheader.e_phnum,
|
numRegions = count_regions(path, pheaderBuffer, eheader.e_phnum,
|
||||||
eheader.e_phentsize);
|
eheader.e_phentsize);
|
||||||
if (numRegions <= 0) {
|
if (numRegions <= 0) {
|
||||||
FATAL("%s: Troubles parsing Program headers, numRegions = %ld\n",
|
FATAL("%s: Troubles parsing Program headers, numRegions = %" B_PRId32
|
||||||
path, numRegions);
|
"\n", path, numRegions);
|
||||||
status = B_BAD_DATA;
|
status = B_BAD_DATA;
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include "runtime_loader_private.h"
|
#include "runtime_loader_private.h"
|
||||||
|
|
||||||
|
|
||||||
status_t parse_elf_header(struct Elf32_Ehdr* eheader, int32* _pheaderSize,
|
status_t parse_elf_header(elf_ehdr* eheader, int32* _pheaderSize,
|
||||||
int32* _sheaderSize);
|
int32* _sheaderSize);
|
||||||
status_t load_image(char const* name, image_type type, const char* rpath,
|
status_t load_image(char const* name, image_type type, const char* rpath,
|
||||||
image_t** _image);
|
image_t** _image);
|
||||||
|
|||||||
@@ -93,28 +93,28 @@ patch_undefined_symbol(image_t* rootImage, image_t* image, const char* name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Elf32_Sym*
|
elf_sym*
|
||||||
find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo)
|
find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo)
|
||||||
{
|
{
|
||||||
if (image->dynamic_ptr == 0)
|
if (image->dynamic_ptr == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Elf32_Sym* versionedSymbol = NULL;
|
elf_sym* versionedSymbol = NULL;
|
||||||
uint32 versionedSymbolCount = 0;
|
uint32 versionedSymbolCount = 0;
|
||||||
|
|
||||||
uint32 bucket = lookupInfo.hash % HASHTABSIZE(image);
|
uint32 bucket = lookupInfo.hash % HASHTABSIZE(image);
|
||||||
|
|
||||||
for (uint32 i = HASHBUCKETS(image)[bucket]; i != STN_UNDEF;
|
for (uint32 i = HASHBUCKETS(image)[bucket]; i != STN_UNDEF;
|
||||||
i = HASHCHAINS(image)[i]) {
|
i = HASHCHAINS(image)[i]) {
|
||||||
Elf32_Sym* symbol = &image->syms[i];
|
elf_sym* symbol = &image->syms[i];
|
||||||
|
|
||||||
if (symbol->st_shndx != SHN_UNDEF
|
if (symbol->st_shndx != SHN_UNDEF
|
||||||
&& ((ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL)
|
&& ((symbol->Bind() == STB_GLOBAL)
|
||||||
|| (ELF32_ST_BIND(symbol->st_info) == STB_WEAK))
|
|| (symbol->Bind() == STB_WEAK))
|
||||||
&& !strcmp(SYMNAME(image, symbol), lookupInfo.name)) {
|
&& !strcmp(SYMNAME(image, symbol), lookupInfo.name)) {
|
||||||
|
|
||||||
// check if the type matches
|
// check if the type matches
|
||||||
uint32 type = ELF32_ST_TYPE(symbol->st_info);
|
uint32 type = symbol->Type();
|
||||||
if ((lookupInfo.type == B_SYMBOL_TYPE_TEXT && type != STT_FUNC)
|
if ((lookupInfo.type == B_SYMBOL_TYPE_TEXT && type != STT_FUNC)
|
||||||
|| (lookupInfo.type == B_SYMBOL_TYPE_DATA
|
|| (lookupInfo.type == B_SYMBOL_TYPE_DATA
|
||||||
&& type != STT_OBJECT)) {
|
&& type != STT_OBJECT)) {
|
||||||
@@ -219,7 +219,7 @@ find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
|
|||||||
void **_location)
|
void **_location)
|
||||||
{
|
{
|
||||||
// get the symbol in the image
|
// get the symbol in the image
|
||||||
Elf32_Sym* symbol = find_symbol(image, lookupInfo);
|
elf_sym* symbol = find_symbol(image, lookupInfo);
|
||||||
if (symbol == NULL)
|
if (symbol == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
@@ -244,16 +244,16 @@ find_symbol_breadth_first(image_t* image, const SymbolLookupInfo& lookupInfo,
|
|||||||
queue[count++] = image;
|
queue[count++] = image;
|
||||||
image->flags |= RFLAG_VISITED;
|
image->flags |= RFLAG_VISITED;
|
||||||
|
|
||||||
Elf32_Sym* candidateSymbol = NULL;
|
elf_sym* candidateSymbol = NULL;
|
||||||
image_t* candidateImage = NULL;
|
image_t* candidateImage = NULL;
|
||||||
|
|
||||||
while (index < count) {
|
while (index < count) {
|
||||||
// pop next image
|
// pop next image
|
||||||
image = queue[index++];
|
image = queue[index++];
|
||||||
|
|
||||||
Elf32_Sym* symbol = find_symbol(image, lookupInfo);
|
elf_sym* symbol = find_symbol(image, lookupInfo);
|
||||||
if (symbol != NULL) {
|
if (symbol != NULL) {
|
||||||
bool isWeak = ELF32_ST_BIND(symbol->st_info) == STB_WEAK;
|
bool isWeak = symbol->Bind() == STB_WEAK;
|
||||||
if (candidateImage == NULL || !isWeak) {
|
if (candidateImage == NULL || !isWeak) {
|
||||||
candidateSymbol = symbol;
|
candidateSymbol = symbol;
|
||||||
candidateImage = image;
|
candidateImage = image;
|
||||||
@@ -294,7 +294,7 @@ find_symbol_breadth_first(image_t* image, const SymbolLookupInfo& lookupInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Elf32_Sym*
|
elf_sym*
|
||||||
find_undefined_symbol_beos(image_t* rootImage, image_t* image,
|
find_undefined_symbol_beos(image_t* rootImage, image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** foundInImage)
|
const SymbolLookupInfo& lookupInfo, image_t** foundInImage)
|
||||||
{
|
{
|
||||||
@@ -303,17 +303,17 @@ find_undefined_symbol_beos(image_t* rootImage, image_t* image,
|
|||||||
// symbol wasn't there. First we check whether the requesting symbol is
|
// symbol wasn't there. First we check whether the requesting symbol is
|
||||||
// defined already -- then we can simply return it, since, due to symbolic
|
// defined already -- then we can simply return it, since, due to symbolic
|
||||||
// linking, that's the one we'd find anyway.
|
// linking, that's the one we'd find anyway.
|
||||||
if (Elf32_Sym* symbol = lookupInfo.requestingSymbol) {
|
if (elf_sym* symbol = lookupInfo.requestingSymbol) {
|
||||||
if (symbol->st_shndx != SHN_UNDEF
|
if (symbol->st_shndx != SHN_UNDEF
|
||||||
&& ((ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL)
|
&& ((symbol->Bind() == STB_GLOBAL)
|
||||||
|| (ELF32_ST_BIND(symbol->st_info) == STB_WEAK))) {
|
|| (symbol->Bind() == STB_WEAK))) {
|
||||||
*foundInImage = image;
|
*foundInImage = image;
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookup in image
|
// lookup in image
|
||||||
Elf32_Sym* symbol = find_symbol(image, lookupInfo);
|
elf_sym* symbol = find_symbol(image, lookupInfo);
|
||||||
if (symbol != NULL) {
|
if (symbol != NULL) {
|
||||||
*foundInImage = image;
|
*foundInImage = image;
|
||||||
return symbol;
|
return symbol;
|
||||||
@@ -334,7 +334,7 @@ find_undefined_symbol_beos(image_t* rootImage, image_t* image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Elf32_Sym*
|
elf_sym*
|
||||||
find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** _foundInImage)
|
const SymbolLookupInfo& lookupInfo, image_t** _foundInImage)
|
||||||
{
|
{
|
||||||
@@ -342,7 +342,7 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
|||||||
// the symbol in the order they have been loaded. We skip add-on images and
|
// the symbol in the order they have been loaded. We skip add-on images and
|
||||||
// RTLD_LOCAL images though.
|
// RTLD_LOCAL images though.
|
||||||
image_t* candidateImage = NULL;
|
image_t* candidateImage = NULL;
|
||||||
Elf32_Sym* candidateSymbol = NULL;
|
elf_sym* candidateSymbol = NULL;
|
||||||
|
|
||||||
// If the requesting image is linked symbolically, look up the symbol there
|
// If the requesting image is linked symbolically, look up the symbol there
|
||||||
// first.
|
// first.
|
||||||
@@ -350,7 +350,7 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
|||||||
if (symbolic) {
|
if (symbolic) {
|
||||||
candidateSymbol = find_symbol(image, lookupInfo);
|
candidateSymbol = find_symbol(image, lookupInfo);
|
||||||
if (candidateSymbol != NULL) {
|
if (candidateSymbol != NULL) {
|
||||||
if (ELF32_ST_BIND(candidateSymbol->st_info) != STB_WEAK) {
|
if (candidateSymbol->Bind() != STB_WEAK) {
|
||||||
*_foundInImage = image;
|
*_foundInImage = image;
|
||||||
return candidateSymbol;
|
return candidateSymbol;
|
||||||
}
|
}
|
||||||
@@ -366,8 +366,8 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
|||||||
: (otherImage->type != B_ADD_ON_IMAGE
|
: (otherImage->type != B_ADD_ON_IMAGE
|
||||||
&& (otherImage->flags
|
&& (otherImage->flags
|
||||||
& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0)) {
|
& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0)) {
|
||||||
if (Elf32_Sym* symbol = find_symbol(otherImage, lookupInfo)) {
|
if (elf_sym* symbol = find_symbol(otherImage, lookupInfo)) {
|
||||||
if (ELF32_ST_BIND(symbol->st_info) != STB_WEAK) {
|
if (symbol->Bind() != STB_WEAK) {
|
||||||
*_foundInImage = otherImage;
|
*_foundInImage = otherImage;
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,7 @@ find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Elf32_Sym*
|
elf_sym*
|
||||||
find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** _foundInImage)
|
const SymbolLookupInfo& lookupInfo, image_t** _foundInImage)
|
||||||
{
|
{
|
||||||
@@ -410,9 +410,9 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
|||||||
// weak symbols that must be resolved globally from those that should be
|
// weak symbols that must be resolved globally from those that should be
|
||||||
// resolved within the add-on.
|
// resolved within the add-on.
|
||||||
if (rootImage == image) {
|
if (rootImage == image) {
|
||||||
if (Elf32_Sym* symbol = lookupInfo.requestingSymbol) {
|
if (elf_sym* symbol = lookupInfo.requestingSymbol) {
|
||||||
if (symbol->st_shndx != SHN_UNDEF
|
if (symbol->st_shndx != SHN_UNDEF
|
||||||
&& (ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL)) {
|
&& (symbol->Bind() == STB_GLOBAL)) {
|
||||||
*_foundInImage = image;
|
*_foundInImage = image;
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
@@ -420,7 +420,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
image_t* candidateImage = NULL;
|
image_t* candidateImage = NULL;
|
||||||
Elf32_Sym* candidateSymbol = NULL;
|
elf_sym* candidateSymbol = NULL;
|
||||||
|
|
||||||
// If the requesting image is linked symbolically, look up the symbol there
|
// If the requesting image is linked symbolically, look up the symbol there
|
||||||
// first.
|
// first.
|
||||||
@@ -428,7 +428,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
|||||||
if (symbolic) {
|
if (symbolic) {
|
||||||
candidateSymbol = find_symbol(image, lookupInfo);
|
candidateSymbol = find_symbol(image, lookupInfo);
|
||||||
if (candidateSymbol != NULL) {
|
if (candidateSymbol != NULL) {
|
||||||
if (ELF32_ST_BIND(candidateSymbol->st_info) != STB_WEAK) {
|
if (candidateSymbol->Bind() != STB_WEAK) {
|
||||||
*_foundInImage = image;
|
*_foundInImage = image;
|
||||||
return candidateSymbol;
|
return candidateSymbol;
|
||||||
}
|
}
|
||||||
@@ -443,8 +443,8 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
|||||||
&& otherImage->type != B_ADD_ON_IMAGE
|
&& otherImage->type != B_ADD_ON_IMAGE
|
||||||
&& (otherImage->flags
|
&& (otherImage->flags
|
||||||
& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0) {
|
& (RTLD_GLOBAL | RFLAG_USE_FOR_RESOLVING)) != 0) {
|
||||||
if (Elf32_Sym* symbol = find_symbol(otherImage, lookupInfo)) {
|
if (elf_sym* symbol = find_symbol(otherImage, lookupInfo)) {
|
||||||
if (ELF32_ST_BIND(symbol->st_info) != STB_WEAK) {
|
if (symbol->Bind() != STB_WEAK) {
|
||||||
*_foundInImage = otherImage;
|
*_foundInImage = otherImage;
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
@@ -473,7 +473,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym,
|
resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym,
|
||||||
SymbolLookupCache* cache, addr_t* symAddress)
|
SymbolLookupCache* cache, addr_t* symAddress)
|
||||||
{
|
{
|
||||||
uint32 index = sym - image->syms;
|
uint32 index = sym - image->syms;
|
||||||
@@ -484,18 +484,18 @@ resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Elf32_Sym* sharedSym;
|
elf_sym* sharedSym;
|
||||||
image_t* sharedImage;
|
image_t* sharedImage;
|
||||||
const char* symName = SYMNAME(image, sym);
|
const char* symName = SYMNAME(image, sym);
|
||||||
|
|
||||||
// get the symbol type
|
// get the symbol type
|
||||||
int32 type = B_SYMBOL_TYPE_ANY;
|
int32 type = B_SYMBOL_TYPE_ANY;
|
||||||
if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC)
|
if (sym->Type() == STT_FUNC)
|
||||||
type = B_SYMBOL_TYPE_TEXT;
|
type = B_SYMBOL_TYPE_TEXT;
|
||||||
else if (ELF32_ST_TYPE(sym->st_info) == STT_OBJECT)
|
else if (sym->Type() == STT_OBJECT)
|
||||||
type = B_SYMBOL_TYPE_DATA;
|
type = B_SYMBOL_TYPE_DATA;
|
||||||
|
|
||||||
if (ELF32_ST_BIND(sym->st_info) == STB_LOCAL) {
|
if (sym->Bind() == STB_LOCAL) {
|
||||||
// Local symbols references are always resolved to the given symbol.
|
// Local symbols references are always resolved to the given symbol.
|
||||||
sharedImage = image;
|
sharedImage = image;
|
||||||
sharedSym = sym;
|
sharedSym = sym;
|
||||||
@@ -526,14 +526,13 @@ resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym,
|
|||||||
// symbol not found at all
|
// symbol not found at all
|
||||||
lookupError = ERROR_NO_SYMBOL;
|
lookupError = ERROR_NO_SYMBOL;
|
||||||
sharedImage = NULL;
|
sharedImage = NULL;
|
||||||
} else if (ELF32_ST_TYPE(sym->st_info) != STT_NOTYPE
|
} else if (sym->Type() != STT_NOTYPE
|
||||||
&& ELF32_ST_TYPE(sym->st_info)
|
&& sym->Type() != sharedSym->Type()) {
|
||||||
!= ELF32_ST_TYPE(sharedSym->st_info)) {
|
|
||||||
// symbol not of the requested type
|
// symbol not of the requested type
|
||||||
lookupError = ERROR_WRONG_TYPE;
|
lookupError = ERROR_WRONG_TYPE;
|
||||||
sharedImage = NULL;
|
sharedImage = NULL;
|
||||||
} else if (ELF32_ST_BIND(sharedSym->st_info) != STB_GLOBAL
|
} else if (sharedSym->Bind() != STB_GLOBAL
|
||||||
&& ELF32_ST_BIND(sharedSym->st_info) != STB_WEAK) {
|
&& sharedSym->Bind() != STB_WEAK) {
|
||||||
// symbol not exported
|
// symbol not exported
|
||||||
lookupError = ERROR_NOT_EXPORTED;
|
lookupError = ERROR_NOT_EXPORTED;
|
||||||
sharedImage = NULL;
|
sharedImage = NULL;
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ struct SymbolLookupInfo {
|
|||||||
uint32 hash;
|
uint32 hash;
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
const elf_version_info* version;
|
const elf_version_info* version;
|
||||||
Elf32_Sym* requestingSymbol;
|
elf_sym* requestingSymbol;
|
||||||
|
|
||||||
SymbolLookupInfo(const char* name, int32 type, uint32 hash,
|
SymbolLookupInfo(const char* name, int32 type, uint32 hash,
|
||||||
const elf_version_info* version = NULL, uint32 flags = 0,
|
const elf_version_info* version = NULL, uint32 flags = 0,
|
||||||
Elf32_Sym* requestingSymbol = NULL)
|
elf_sym* requestingSymbol = NULL)
|
||||||
:
|
:
|
||||||
name(name),
|
name(name),
|
||||||
type(type),
|
type(type),
|
||||||
@@ -42,7 +42,7 @@ struct SymbolLookupInfo {
|
|||||||
|
|
||||||
SymbolLookupInfo(const char* name, int32 type,
|
SymbolLookupInfo(const char* name, int32 type,
|
||||||
const elf_version_info* version = NULL, uint32 flags = 0,
|
const elf_version_info* version = NULL, uint32 flags = 0,
|
||||||
Elf32_Sym* requestingSymbol = NULL)
|
elf_sym* requestingSymbol = NULL)
|
||||||
:
|
:
|
||||||
name(name),
|
name(name),
|
||||||
type(type),
|
type(type),
|
||||||
@@ -115,17 +115,17 @@ void patch_undefined_symbol(image_t* rootImage, image_t* image,
|
|||||||
const char* name, image_t** foundInImage, void** symbol,
|
const char* name, image_t** foundInImage, void** symbol,
|
||||||
int32* type);
|
int32* type);
|
||||||
|
|
||||||
Elf32_Sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo);
|
elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo);
|
||||||
status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
|
status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
|
||||||
void** _location);
|
void** _location);
|
||||||
status_t find_symbol_breadth_first(image_t* image,
|
status_t find_symbol_breadth_first(image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** _foundInImage,
|
const SymbolLookupInfo& lookupInfo, image_t** _foundInImage,
|
||||||
void** _location);
|
void** _location);
|
||||||
Elf32_Sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image,
|
elf_sym* find_undefined_symbol_beos(image_t* rootImage, image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
|
const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
|
||||||
Elf32_Sym* find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
elf_sym* find_undefined_symbol_global(image_t* rootImage, image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
|
const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
|
||||||
Elf32_Sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
elf_sym* find_undefined_symbol_add_on(image_t* rootImage, image_t* image,
|
||||||
const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
|
const SymbolLookupInfo& lookupInfo, image_t** foundInImage);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ assert_defined_image_version(image_t* dependentImage, image_t* image,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// iterate through the defined versions to find the given one
|
// iterate through the defined versions to find the given one
|
||||||
Elf32_Verdef* definition = image->version_definitions;
|
elf_verdef* definition = image->version_definitions;
|
||||||
for (uint32 i = 0; i < image->num_version_definitions; i++) {
|
for (uint32 i = 0; i < image->num_version_definitions; i++) {
|
||||||
uint32 versionIndex = VER_NDX(definition->vd_ndx);
|
uint32 versionIndex = VER_NDX(definition->vd_ndx);
|
||||||
elf_version_info& info = image->versions[versionIndex];
|
elf_version_info& info = image->versions[versionIndex];
|
||||||
@@ -36,8 +36,7 @@ assert_defined_image_version(image_t* dependentImage, image_t* image,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
definition = (Elf32_Verdef*)
|
definition = (elf_verdef*)((uint8*)definition + definition->vd_next);
|
||||||
((uint8*)definition + definition->vd_next);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// version not found -- fail, if not weak
|
// version not found -- fail, if not weak
|
||||||
@@ -63,7 +62,7 @@ init_image_version_infos(image_t* image)
|
|||||||
uint32 maxIndex = 0;
|
uint32 maxIndex = 0;
|
||||||
|
|
||||||
if (image->version_definitions != NULL) {
|
if (image->version_definitions != NULL) {
|
||||||
Elf32_Verdef* definition = image->version_definitions;
|
elf_verdef* definition = image->version_definitions;
|
||||||
for (uint32 i = 0; i < image->num_version_definitions; i++) {
|
for (uint32 i = 0; i < image->num_version_definitions; i++) {
|
||||||
if (definition->vd_version != 1) {
|
if (definition->vd_version != 1) {
|
||||||
FATAL("%s: Unsupported version definition revision: %u\n",
|
FATAL("%s: Unsupported version definition revision: %u\n",
|
||||||
@@ -75,13 +74,13 @@ init_image_version_infos(image_t* image)
|
|||||||
if (versionIndex > maxIndex)
|
if (versionIndex > maxIndex)
|
||||||
maxIndex = versionIndex;
|
maxIndex = versionIndex;
|
||||||
|
|
||||||
definition = (Elf32_Verdef*)
|
definition = (elf_verdef*)
|
||||||
((uint8*)definition + definition->vd_next);
|
((uint8*)definition + definition->vd_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image->needed_versions != NULL) {
|
if (image->needed_versions != NULL) {
|
||||||
Elf32_Verneed* needed = image->needed_versions;
|
elf_verneed* needed = image->needed_versions;
|
||||||
for (uint32 i = 0; i < image->num_needed_versions; i++) {
|
for (uint32 i = 0; i < image->num_needed_versions; i++) {
|
||||||
if (needed->vn_version != 1) {
|
if (needed->vn_version != 1) {
|
||||||
FATAL("%s: Unsupported version needed revision: %u\n",
|
FATAL("%s: Unsupported version needed revision: %u\n",
|
||||||
@@ -89,17 +88,17 @@ init_image_version_infos(image_t* image)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf32_Vernaux* vernaux
|
elf_vernaux* vernaux
|
||||||
= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
|
= (elf_vernaux*)((uint8*)needed + needed->vn_aux);
|
||||||
for (uint32 k = 0; k < needed->vn_cnt; k++) {
|
for (uint32 k = 0; k < needed->vn_cnt; k++) {
|
||||||
uint32 versionIndex = VER_NDX(vernaux->vna_other);
|
uint32 versionIndex = VER_NDX(vernaux->vna_other);
|
||||||
if (versionIndex > maxIndex)
|
if (versionIndex > maxIndex)
|
||||||
maxIndex = versionIndex;
|
maxIndex = versionIndex;
|
||||||
|
|
||||||
vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
|
vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
|
needed = (elf_verneed*)((uint8*)needed + needed->vn_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,12 +118,12 @@ init_image_version_infos(image_t* image)
|
|||||||
|
|
||||||
// version definitions
|
// version definitions
|
||||||
if (image->version_definitions != NULL) {
|
if (image->version_definitions != NULL) {
|
||||||
Elf32_Verdef* definition = image->version_definitions;
|
elf_verdef* definition = image->version_definitions;
|
||||||
for (uint32 i = 0; i < image->num_version_definitions; i++) {
|
for (uint32 i = 0; i < image->num_version_definitions; i++) {
|
||||||
if (definition->vd_cnt > 0
|
if (definition->vd_cnt > 0
|
||||||
&& (definition->vd_flags & VER_FLG_BASE) == 0) {
|
&& (definition->vd_flags & VER_FLG_BASE) == 0) {
|
||||||
Elf32_Verdaux* verdaux
|
elf_verdaux* verdaux
|
||||||
= (Elf32_Verdaux*)((uint8*)definition + definition->vd_aux);
|
= (elf_verdaux*)((uint8*)definition + definition->vd_aux);
|
||||||
|
|
||||||
uint32 versionIndex = VER_NDX(definition->vd_ndx);
|
uint32 versionIndex = VER_NDX(definition->vd_ndx);
|
||||||
elf_version_info& info = image->versions[versionIndex];
|
elf_version_info& info = image->versions[versionIndex];
|
||||||
@@ -133,19 +132,19 @@ init_image_version_infos(image_t* image)
|
|||||||
info.file_name = NULL;
|
info.file_name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
definition = (Elf32_Verdef*)
|
definition = (elf_verdef*)
|
||||||
((uint8*)definition + definition->vd_next);
|
((uint8*)definition + definition->vd_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// needed versions
|
// needed versions
|
||||||
if (image->needed_versions != NULL) {
|
if (image->needed_versions != NULL) {
|
||||||
Elf32_Verneed* needed = image->needed_versions;
|
elf_verneed* needed = image->needed_versions;
|
||||||
for (uint32 i = 0; i < image->num_needed_versions; i++) {
|
for (uint32 i = 0; i < image->num_needed_versions; i++) {
|
||||||
const char* fileName = STRING(image, needed->vn_file);
|
const char* fileName = STRING(image, needed->vn_file);
|
||||||
|
|
||||||
Elf32_Vernaux* vernaux
|
elf_vernaux* vernaux
|
||||||
= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
|
= (elf_vernaux*)((uint8*)needed + needed->vn_aux);
|
||||||
for (uint32 k = 0; k < needed->vn_cnt; k++) {
|
for (uint32 k = 0; k < needed->vn_cnt; k++) {
|
||||||
uint32 versionIndex = VER_NDX(vernaux->vna_other);
|
uint32 versionIndex = VER_NDX(vernaux->vna_other);
|
||||||
elf_version_info& info = image->versions[versionIndex];
|
elf_version_info& info = image->versions[versionIndex];
|
||||||
@@ -153,10 +152,10 @@ init_image_version_infos(image_t* image)
|
|||||||
info.name = STRING(image, vernaux->vna_name);
|
info.name = STRING(image, vernaux->vna_name);
|
||||||
info.file_name = fileName;
|
info.file_name = fileName;
|
||||||
|
|
||||||
vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
|
vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
|
needed = (elf_verneed*)((uint8*)needed + needed->vn_next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +169,7 @@ check_needed_image_versions(image_t* image)
|
|||||||
if (image->needed_versions == NULL)
|
if (image->needed_versions == NULL)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
Elf32_Verneed* needed = image->needed_versions;
|
elf_verneed* needed = image->needed_versions;
|
||||||
for (uint32 i = 0; i < image->num_needed_versions; i++) {
|
for (uint32 i = 0; i < image->num_needed_versions; i++) {
|
||||||
const char* fileName = STRING(image, needed->vn_file);
|
const char* fileName = STRING(image, needed->vn_file);
|
||||||
image_t* dependency = find_loaded_image_by_name(fileName,
|
image_t* dependency = find_loaded_image_by_name(fileName,
|
||||||
@@ -183,8 +182,8 @@ check_needed_image_versions(image_t* image)
|
|||||||
return B_FILE_NOT_FOUND;
|
return B_FILE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
Elf32_Vernaux* vernaux
|
elf_vernaux* vernaux
|
||||||
= (Elf32_Vernaux*)((uint8*)needed + needed->vn_aux);
|
= (elf_vernaux*)((uint8*)needed + needed->vn_aux);
|
||||||
for (uint32 k = 0; k < needed->vn_cnt; k++) {
|
for (uint32 k = 0; k < needed->vn_cnt; k++) {
|
||||||
uint32 versionIndex = VER_NDX(vernaux->vna_other);
|
uint32 versionIndex = VER_NDX(vernaux->vna_other);
|
||||||
elf_version_info& info = image->versions[versionIndex];
|
elf_version_info& info = image->versions[versionIndex];
|
||||||
@@ -194,10 +193,10 @@ check_needed_image_versions(image_t* image)
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
vernaux = (Elf32_Vernaux*)((uint8*)vernaux + vernaux->vna_next);
|
vernaux = (elf_vernaux*)((uint8*)vernaux + vernaux->vna_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
needed = (Elf32_Verneed*)((uint8*)needed + needed->vn_next);
|
needed = (elf_verneed*)((uint8*)needed + needed->vn_next);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ update_image_id(image_t* image)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FATAL("Could not update image ID %ld after fork()!\n", image->id);
|
FATAL("Could not update image ID %" B_PRId32 " after fork()!\n", image->id);
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,7 +330,7 @@ map_image(int fd, char const* path, image_t* image, bool fixed)
|
|||||||
for (uint32 i = 0; i < image->num_regions; i++) {
|
for (uint32 i = 0; i < image->num_regions; i++) {
|
||||||
char regionName[B_OS_NAME_LENGTH];
|
char regionName[B_OS_NAME_LENGTH];
|
||||||
|
|
||||||
snprintf(regionName, sizeof(regionName), "%s_seg%lu%s",
|
snprintf(regionName, sizeof(regionName), "%s_seg%" B_PRIu32 "%s",
|
||||||
baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
|
baseName, i, (image->regions[i].flags & RFLAG_RW) ? "rw" : "ro");
|
||||||
|
|
||||||
get_image_region_load_address(image, i,
|
get_image_region_load_address(image, i,
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "runtime_loader_private.h"
|
#include "runtime_loader_private.h"
|
||||||
|
|
||||||
#include <elf32.h>
|
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <user_runtime.h>
|
#include <user_runtime.h>
|
||||||
|
|
||||||
@@ -348,7 +347,7 @@ test_executable(const char *name, char *invoker)
|
|||||||
status = B_OK;
|
status = B_OK;
|
||||||
}
|
}
|
||||||
} else if (status == B_OK) {
|
} else if (status == B_OK) {
|
||||||
struct Elf32_Ehdr *elfHeader = (struct Elf32_Ehdr *)buffer;
|
elf_ehdr *elfHeader = (elf_ehdr *)buffer;
|
||||||
if (elfHeader->e_entry == 0) {
|
if (elfHeader->e_entry == 0) {
|
||||||
// we don't like to open shared libraries
|
// we don't like to open shared libraries
|
||||||
status = B_NOT_AN_EXECUTABLE;
|
status = B_NOT_AN_EXECUTABLE;
|
||||||
|
|||||||
@@ -73,11 +73,11 @@ status_t get_library_symbol(void* handle, void* caller, const char* symbolName,
|
|||||||
void** _location);
|
void** _location);
|
||||||
status_t get_next_image_dependency(image_id id, uint32* cookie,
|
status_t get_next_image_dependency(image_id id, uint32* cookie,
|
||||||
const char** _name);
|
const char** _name);
|
||||||
int resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym,
|
int resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym,
|
||||||
SymbolLookupCache* cache, addr_t* sym_addr);
|
SymbolLookupCache* cache, addr_t* sym_addr);
|
||||||
|
|
||||||
|
|
||||||
status_t elf_verify_header(void* header, int32 length);
|
status_t elf_verify_header(void* header, size_t length);
|
||||||
void rldelf_init(void);
|
void rldelf_init(void);
|
||||||
void rldexport_init(void);
|
void rldexport_init(void);
|
||||||
status_t elf_reinit_after_fork(void);
|
status_t elf_reinit_after_fork(void);
|
||||||
|
|||||||
Reference in New Issue
Block a user