Symbol look up in an position independent so file - c

I am writing a code to find a symbol within an ELF file.
In my code I open an ELF file, map all the segments to memory and store all the information related to various section and tables in a structure like this.
typedef struct Struct_Obj_Entry{
//Name of the file
const char *filepath;
//File pointer
void* ELF_fp;
//Metadata of ELF header and Progam header tables
Elf32_Ehdr* Ehdr;
Elf32_Phdr* Phdr_array;
//base address of mapped region
uint32 mapbase;
//DYNAMIC Segment
uint32 *dynamic;
//DT_SYMTAB
Elf32_Sym *symtab; //Ptr to DT_SYMTAB
//DT_STRTAB
char *strtab;
//DT_HASH
uint32 *hashtab;//Ptr to DT_HASH
//Hash table variables
int nbuckets, nchains;
uint32 *buckets,
*chains;
} Obj_Entry;
This portion works perfectly fine and all the struct elements are correctly populated holding valid addresses to the regions of mapped ELF file.
Here is how I search for a symbol name,
void *return_symbol_vaddr(Obj_Entry *obj, const char *name){
unsigned long hash_value;
uint32 y=0,z=0;
/*following part is DLSYM code to locate a symbol in a given file*/
//Lets query for a symbol name
hash_value = elf_Hash(name);
printf("hash value =%lu\n",hash_value);
//See if correct symbol entry found in bucket list
//If it is break out
y = (obj->buckets[hash_value % obj->nbuckets]);
if((!strcmp(name, obj->strtab + obj->symtab[z].st_name))) {
return (void*)(obj->mapbase + (obj->symtab[z]).st_value);
}
//If not there is a collision
else{
while(obj->chains[y] !=0){
z = obj->chains[y];
if((!strcmp(name, obj->strtab + obj->symtab[z].st_name))) {
//return (void*)(obj->symtab[z].st_value);
return (void*)(obj->mapbase + obj->symtab[z].st_value);
}
else{
//If the symbol is not found in chains
//There is double collision
//In that case chain[y] gives the next symbol table entry with the same hash value
y = z;
}
}
}
}
The string hash function is a standard ABI specification:
//Get hash value for a symbol name
unsigned long
elf_Hash(const unsigned char *name)
{
unsigned long h = 0, g;
while (*name)
{
h = (h << 4) + *name++;
if (g = h & 0xf0000000)
h ^= g >> 24;
h &= ~g;
}
return h;
}
Now the problem is when I compile a position independent so file and try to look for symbols. I am able to find some of the symbol and for rest of them the function returns NULL value.
Example ELF file
typedef struct _data{
int x;
int y;
}data;
int add(void){
return 1;
}
int sub(void){
return 4;
}
data Data ={3, 2};
When I compile this file to an ELF I can find add, Data symbols but surprisingly enough I cant find 'sub'. When I do a readelf on the .so file I can see that sub appears in DT_SYMTAB list of dynamic symbols.
Anybody can pin-point to a code bug?
Here is a link to how symbols are packed in an so
http://docs.oracle.com/cd/E19082-01/819-0690/chapter6-48031/index.html

Related

File System Open Files Randomly

One of my clients asked me to play sound from an SD card. But file selection should be random because the device is used to scare animals in the field(animals should not get used to sound pattern). I can generate random numbers by
void RNG_Generate_Numbers()
{
HAL_RNG_GenerateRandomNumber(&hrng, &random_number.random_number1);
HAL_RNG_GenerateRandomNumber(&hrng, &random_number.random_number2);
}
And I can count files via
void File_Find_File(file_manager_t *file_manage)
{
file_manage->file_result = f_readdir(&file_manage->file_direction, &file_manage->file_info);
if( (file_manage->file_result != FR_OK) || (file_manage->file_info.fname[0] == '\0') )
{
file_manage->file_counter = 0;
}
else
{
++file_manage->file_counter;
}
}
Everything till here is just fine. But when It comes to select files randomly, I could not find any method to do it. Any help is appreciated.
Edit: This is file_manager structure;
typedef struct __file_manager /* struct tag */
{
FATFS drive_handler;
FIL file_handler;
FRESULT file_result;
uint8_t file_disk_status;
DIR file_direction;
FILINFO file_info;
uint8_t file_rx_buffer[512];
char file_current_dir[256];
uint32_t file_bytes_read;
uint32_t file_bytes_write;
size_t file_counter;
}file_manager_t ;
The simplest solution would be to move all files into a single directory and name each file in a sequence starting from zero. Getting a random files name would then be as simple as:
sprintf(file_name, "%d.mp3", rand() % my_files);

Reading structure tags from a header file?

So I wanted to configure different structures for which I have a header file such as:
header.h
typedef struct
{
uint32_t hola;
uint32_t adios;
}Signal_t;
typedef struct
{
bool goodbye;
uint32_t hello;
} FrameTx_t;
In order to do so, at some point, within my source code, I will need to detect which kind of structure is to be configured by the received text.
id. est: If I have a JSON file that goes somewhere along:
JSON_File.txt
{"Signal_t" :
{
"hola" : 1024,
"adios" : 555555
}
}
I need to recognize that the to-be-configured structure is of type Signal_t.
For now I have developed a simple code in which, after parsing the text, I can obtain the name of the structure in a string format, and then I created the following function to determine which structure is to be configured:
Code.c
int structure_Select(char* structName, int sizeOfStructName) {
char Signal_tName[] = "Signal_t";
char FrameTx_tName[] = "FrameTx_t";
int idx=0;
if ((sizeof(Signal_tName) - 1) == sizeOfStructName) {
for (idx = 0;idx < sizeOfStructName;idx++) {
if (Signal_tName[idx] != structName[idx]) {
break;
}
}
if (idx == sizeOfStructName) {
printf("%s", Signal_tName);
return 0;
}
}
if ((sizeof(FrameTx_tName) - 1) == sizeOfStructName) {
for (idx = 0;idx < sizeOfStructName;idx++) {
if (FrameTx_tName[idx] != structName[idx]) {
break;
}
}
if (idx == sizeOfStructName) {
printf("%s", FrameTx_tName);
return 1;
}
}
}
I can assure you it works; it just does not go as "automatic" as I would like it to be...
I would like for the program to be able to read the header file and automatically recognize: "Oh okay, so I'm dealing with a Signal_t data type, I'm gonna then read two different data from the stream and assign data1 to Signal_t.hola and data2 to Signal_t.adios"
The assignation is clearly not a problem; only determining from an existing structure within a file the name of it or a way to differentiate between structs.
So far I've thought about the following possibilities outside of what I already have, but I'm cycled within it:
o Create a mini "C-structure parser" function
o Is there ANY way to get the name of a structure tag within C that I don't know of?
I'm open to suggestions, whether it's just ideas that I could work on and I'm not seeing or if any of you has dealed with a similar issue in the past and instead of using a list of char variables, actually reads the header file for the structure names... thanks in advance!
.
.
.
TL;DR: Is there any way to read structures' tags from a header file as a string?
Edit: This is what I mean with structure tag/type alias:
//structure to get a rectangle
typedef struct {
int left;
int bottom;
int right;
int top;
} rect_t; //this rect_t is what I mean by structure tag...
//I checked the name and it should be type alias***

Find pathname from dlopen handle on OSX

I have dlopen()'ed a library, and I want to invert back from the handle it passes to me to the full pathname of shared library. On Linux and friends, I know that I can use dlinfo() to get the linkmap and iterate through those structures, but I can't seem to find an analogue on OSX. The closest thing I can do is to either:
Use dyld_image_count() and dyld_get_image_name(), iterate over all the currently opened libraries and hope I can guess which one corresponds to my handle
Somehow find a symbol that lives inside of the handle I have, and pass that to dladdr().
If I have apriori knowledge as to a symbol name inside of the library I just opened, I can dlsym() that and then use dladdr(). That works fine. But in the general case where I have no idea what is inside this shared library, I would need to be able to enumerate symbols to do that, which I don't know how to do either.
So any tips on how to lookup the pathname of a library from its dlopen handle would be very much appreciated. Thanks!
Here is how you can get the absolute path of a handle returned by dlopen.
In order to get the absolute path, you need to call the dladdr function and retrieve the Dl_info.dli_fname field.
In order to call the dladdr function, you need to give it an address.
In order to get an address given a handle, you have to call the dlsym function with a symbol.
In order to get a symbol out of a loaded library, you have to parse the library to find its symbol table and iterate over the symbols. You need to find an external symbol because dlsym only searches for external symbols.
Put it all together and you get this:
#import <dlfcn.h>
#import <mach-o/dyld.h>
#import <mach-o/nlist.h>
#import <stdio.h>
#import <string.h>
#ifdef __LP64__
typedef struct mach_header_64 mach_header_t;
typedef struct segment_command_64 segment_command_t;
typedef struct nlist_64 nlist_t;
#else
typedef struct mach_header mach_header_t;
typedef struct segment_command segment_command_t;
typedef struct nlist nlist_t;
#endif
static const char * first_external_symbol_for_image(const mach_header_t *header)
{
Dl_info info;
if (dladdr(header, &info) == 0)
return NULL;
segment_command_t *seg_linkedit = NULL;
segment_command_t *seg_text = NULL;
struct symtab_command *symtab = NULL;
struct load_command *cmd = (struct load_command *)((intptr_t)header + sizeof(mach_header_t));
for (uint32_t i = 0; i < header->ncmds; i++, cmd = (struct load_command *)((intptr_t)cmd + cmd->cmdsize))
{
switch(cmd->cmd)
{
case LC_SEGMENT:
case LC_SEGMENT_64:
if (!strcmp(((segment_command_t *)cmd)->segname, SEG_TEXT))
seg_text = (segment_command_t *)cmd;
else if (!strcmp(((segment_command_t *)cmd)->segname, SEG_LINKEDIT))
seg_linkedit = (segment_command_t *)cmd;
break;
case LC_SYMTAB:
symtab = (struct symtab_command *)cmd;
break;
}
}
if ((seg_text == NULL) || (seg_linkedit == NULL) || (symtab == NULL))
return NULL;
intptr_t file_slide = ((intptr_t)seg_linkedit->vmaddr - (intptr_t)seg_text->vmaddr) - seg_linkedit->fileoff;
intptr_t strings = (intptr_t)header + (symtab->stroff + file_slide);
nlist_t *sym = (nlist_t *)((intptr_t)header + (symtab->symoff + file_slide));
for (uint32_t i = 0; i < symtab->nsyms; i++, sym++)
{
if ((sym->n_type & N_EXT) != N_EXT || !sym->n_value)
continue;
return (const char *)strings + sym->n_un.n_strx;
}
return NULL;
}
const char * pathname_for_handle(void *handle)
{
for (int32_t i = _dyld_image_count(); i >= 0 ; i--)
{
const char *first_symbol = first_external_symbol_for_image((const mach_header_t *)_dyld_get_image_header(i));
if (first_symbol && strlen(first_symbol) > 1)
{
handle = (void *)((intptr_t)handle | 1); // in order to trigger findExportedSymbol instead of findExportedSymbolInImageOrDependentImages. See `dlsym` implementation at http://opensource.apple.com/source/dyld/dyld-239.3/src/dyldAPIs.cpp
first_symbol++; // in order to remove the leading underscore
void *address = dlsym(handle, first_symbol);
Dl_info info;
if (dladdr(address, &info))
return info.dli_fname;
}
}
return NULL;
}
int main(int argc, const char * argv[])
{
void *libxml2 = dlopen("libxml2.dylib", RTLD_LAZY);
printf("libxml2 path: %s\n", pathname_for_handle(libxml2));
dlclose(libxml2);
return 0;
}
If you run this code, it will yield the expected result: libxml2 path: /usr/lib/libxml2.2.dylib
After about a year of using the solution provided by 0xced, we discovered an alternative method that is simpler and avoids one (rather rare) failure mode; specifically, because 0xced's code snippet iterates through each dylib currently loaded, finds the first exported symbol, attempts to resolve it in the dylib currently being sought, and returns positive if that symbol is found in that particular dylib, you can have false positives if the first exported symbol from an arbitrary library happens to be present inside of the dylib you're currently searching for.
My solution was to use _dyld_get_image_name(i) to get the absolute path of each image loaded, dlopen() that image, and compare the handle (after masking out any mode bits set by dlopen() due to usage of things like RTLD_FIRST) to ensure that this dylib is actually the same file as the handle passed into my function.
The complete function can be seen here, as a part of the Julia Language, with the relevant portion copied below:
// Iterate through all images currently in memory
for (int32_t i = _dyld_image_count(); i >= 0 ; i--) {
// dlopen() each image, check handle
const char *image_name = _dyld_get_image_name(i);
uv_lib_t *probe_lib = jl_load_dynamic_library(image_name, JL_RTLD_DEFAULT);
void *probe_handle = probe_lib->handle;
uv_dlclose(probe_lib);
// If the handle is the same as what was passed in (modulo mode bits), return this image name
if (((intptr_t)handle & (-4)) == ((intptr_t)probe_handle & (-4)))
return image_name;
}
Note that functions such as jl_load_dynamic_library() are wrappers around dlopen() that return libuv types, but the spirit of the code remains the same.

Pointers getting junk values outside of functions, but regular values inside them

Full disclosure: This is my first time doing any significant programming in C, and my first post on Stack Overflow.
I'm working on code that will eventually be used with Bison to implement a small subset of the Scheme/Racket language. All of this code is in a single C file. I have three structs: Binding, Lambda, and SymbolEntry. I'm not using the Lambda struct yet, it's just there for completeness. I also have a symbol table that holds symbol entries. printSymbolTable() does exactly what the name implies:
typedef struct
{
char* name;
char* value;
} Binding;
typedef struct
{
int numBindings;
Binding** bindings;
char* functionBody;
} Lambda;
typedef struct
{
Binding* binding;
Lambda* function;
} SymbolEntry;
SymbolEntry* symbolTable = NULL;
int numSymbols = 0;
void printSymbolTable()
{
if (symbolTable)
{
int i = 0;
for (i; i < numSymbols; i++)
{
printf("\tsymbolTable[%i]: %s = %s\n", i, symbolTable[i].binding->name, symbolTable[i].binding->value);
}
}
}
I'm currently trying to work out the logic for defining and looking up variables. The 2 relevant functions:
// Takes a name and an exprssion and stores the result in the symbol table
void defineVar(char* name, char* expr)
{
printf("\nSetting %s = %s\n", name, expr);
printf("Previous number of symbols: %i\n", numSymbols);
Binding props;
props.name = name;
props.value = expr;
SymbolEntry entry;
entry.binding = &props;
entry.function = NULL;
symbolTable = realloc(symbolTable, sizeof(SymbolEntry) * ++numSymbols);
if (!symbolTable)
{
printf("Memory allocation failed. Exiting.\n");
exit(1);
}
symbolTable[numSymbols - 1] = entry;
printf("New number of symbols: %i\n", numSymbols);
printf("defineVar result:\n");
printSymbolTable();
}
// Test storing and looking up at least 4 variables, including one that is undefined
void testVars()
{
printf("Variable tests\n");
defineVar("foo", "0");
printf("After returning from defineVar:\n");
printSymbolTable();
defineVar("bar", "20");
printf("After returning from defineVar:\n");
printSymbolTable();
}
main() calls testVars(). I get no warnings or errors when compiling, and the program executes successfully. However, this is the result:
Variable tests
Setting foo = 0
Previous number of symbols: 0
New number of symbols: 1
defineVar result:
symbolTable[0]: foo = 0
After returning from defineVar:
symbolTable[0]: 1�I��^H��H���PTI��# = �E
Setting bar = 20
Previous number of symbols: 1
New number of symbols: 2
defineVar result:
symbolTable[0]: bar = 20
symbolTable[1]: bar = 20
After returning from defineVar:
symbolTable[0]: 1�I��^H��H���PTI��# = �E
symbolTable[1]: 1�I��^H��H���PTI��# = �E���
Not only am I getting junk values when outside of the defineVar() function, but the call to define bar shows incorrect non-junk values as well. I'm not sure what I'm doing wrong, but I assume it's probably something with realloc(). However, a similar strategy worked when parsing a string into individual tokens, so that's what I was trying to emulate. What am I doing wrong?
Because it's pointing to variables (or variable — at least props, haven't read further) local to functions and the stack frame is discarded (and soon overwritten) after you return.

External Functions and Parameter Size Limitation (C)

I am very much stuck in the following issue. Any help is very much appreciated!
Basically I have a program wich contains an array of structs and I am getting a segmentation error when I call an external function. The error only happens when I have more than 170 items on the array being passed.
Nothing on the function is processed. The program stops exactly when accessing the function.
Is there a limit for the size of the parameters that are passed to external functions?
Main.c
struct ratingObj {
int uid;
int mid;
double rating;
};
void *FunctionLib; /* Handle to shared lib file */
void (*Function)(); /* Pointer to loaded routine */
const char *dlError; /* Pointer to error string */
int main( int argc, char * argv[]){
// ... some code ...
asprintf(&query, "select mid, rating "
"from %s "
"where uid=%d "
"order by rand()", itable, uid);
if (mysql_query(conn2, query)) {
fprintf(stderr, "%s\n", mysql_error(conn2));
exit(1);
}
res2 = mysql_store_result(conn2);
int movieCount = mysql_num_rows(res2);
// withhold is a variable that defines a percentage of the entries
// to be used for calculations (generally 20%)
int listSize = round((movieCount * ((double)withhold/100)));
struct ratingObj moviesToRate[listSize];
int mvCount = 0;
int count =0;
while ((row2 = mysql_fetch_row(res2)) != NULL){
if(count<(movieCount-listSize)){
// adds to another table
}else{
moviesToRate[mvCount].uid = uid;
moviesToRate[mvCount].mid = atoi(row2[0]);
moviesToRate[mvCount].rating = 0.0;
mvCount++;
}
count++;
}
// ... more code ...
FunctionLib = dlopen("library.so", RTLD_LAZY);
dlError = dlerror();
if( dlError ) exit(1);
Function = dlsym( FunctionLib, "getResults");
dlError = dlerror();
(*Function)( moviesToRate, listSize );
// .. more code
}
library.c
struct ratingObj {
int uid;
int mid;
double rating;
};
typedef struct ratingObj ratingObj;
void getResults(struct ratingObj *moviesToRate, int listSize);
void getResults(struct ratingObj *moviesToRate, int listSize){
// ... more code
}
You are likely blowing up the stack. Move the array to outside of the function, i.e. from auto to static land.
Another option is that the // ... more code - array gets populated... part is corrupting the stack.
Edit 0:
After you posted more code - you are using C99 variable sized array on the stack - Bad IdeaTM. Think what happens when your data set grows to thousands, or millions, of records. Switch to dynamic memory allocation, see malloc(3).
You don't show us what listsize is, but I suppose it is a variable and not a constant.
What you are using are variable length arrays, VLA. These are a bit dangerous if they are too large since they usually allocated on the stack.
To work around that you can allocate such a beast dynamically
struct ratingObj (*movies)[listSize] = malloc(sizeof(*movies));
// ...
free(movies);
You'd then have in mind though that movies then is a pointer to array, so you have to reference with one * more than before.
Another, more classical C version would be
struct ratingObj * movies = malloc(sizeof(*movies)*listsize);
// ...
free(movies);

Resources