Print symbol of file .o - symbols

I want to print symbol of .o file (same of nm command).
I iterate on each section. And use this condition:
if (section[i].sh_type == SHT_SYMTAB)
{
sym = (Elf64_Sym *)((char *)content +
section[i].sh_offset);
}
When I have my Elf64_Sym struct, i want print the symbol name. The struct is:
typedef struct {
uint32_t st_name;
unsigned char st_info;
unsigned char st_other;
uint16_t st_shndx;
Elf64_Addr st_value;
uint64_t st_size;
} Elf64_Sym;
How to print the st_name ? His type is uint32_t.
I don't understand how to print it.
An idea ?
Thanks you !

the st_name is an offset in the .shstrtab.
The string you're searching for is (char *)(addr of shstrtab) + sym->st_name;

Related

Converting NSStrings to C chars and calling a C function from Objective-C

I'm in an Objective-C method with various NSStrings that I want to pass to a C function. The C function requires a struct object be malloc'd so that it can be passed in - this struct contains char fields. So the struct is defined like this:
struct libannotate_baseManual {
char *la_bm_code; // The base code for this manual (pointer to malloc'd memory)
char *la_bm_effectiveRevisionId; // The currently effective revision ID (pointer to malloc'd memory or null if none effective)
char **la_bm_revisionId; // The null-terminated list of revision IDs in the library for this manual (pointer to malloc'd array of pointers to malloc'd memory)
};
This struct is then used in the following C function definition:
void libannotate_setManualLibrary(struct libannotate_baseManual **library) { ..
So that's the function I need to call from Objective-C.
So I have various NSStrings that I basically want to pass in there, to represent the chars - la_bm_code, la_bm_effectiveRevisionId, la_bm_revision. I could convert those to const chars by using [NSString UTF8String], but I need chars, not const chars.
Also I need to do suitable malloc's for these fields, though apparently I don't need to worry about freeing the memory afterwards. C is not my strong point, though I know Objective-C well.
strdup() is your friend here as that both malloc()s and strcpy()s for you in one simple step. It's memory is also released using free() and it does your const char * to char * conversion for you!
NSString *code = ..., *effectiveRevId = ..., *revId = ...;
struct libannotate_baseManual *abm = malloc(sizeof(struct libannotate_baseManual));
abm->la_bm_code = strdup([code UTF8String]);
abm->la_bm_effectiveRevisionId = strdup([effectiveRevId UTF8String]);
const unsigned numRevIds = 1;
abm->la_bm_effectiveRevisionId = malloc(sizeof(char *) * (numRevIds + 1));
abm->la_bm_effectiveRevisionId[0] = strdup([revId UTF8String]);
abm->la_bm_effectiveRevisionId[1] = NULL;
const unsigned numAbms = 1;
struct libannotate_baseManual **abms = malloc(sizeof(struct libannotate_baseManual *) * (numAbms + 1));
abms[0] = abm;
abms[1] = NULL;
libannotate_setManualLibrary(abms);
Good luck, you'll need it. It's one of the worst interfaces I've ever seen.

Suspicious pointer conversion

I got a suspicious pointer conversion error here. What might be the reason of this error?
I also initialized the code[] array globally as int *code[128]={0};
void encode(const char *s, int *out)
{
while(*s)
{
out=code[*s];
out+=strlen(code[*s++]); //this is where i got the error.
}
}
When you will assign a particular type pointer variable with address of different type, such type of automatic type conversion is known as suspicious type conversion.
strlen requires const char *, while int *code[128] means code is an array of int *, so code[*s++] is a int *.
When int * is supplied to const char *, you get this error.
Generally supply int * pointer to strlen isn't a good idea because strlen will end when a byte is '\0'. You have a good chance to have 0 in a 4 bytes int. E.g., an integer 3 will have 3 bytes of 0, and 1 byte of 3.

How to convert long long to 8 byte array in objective C

In my application i have to convert long long number into 8 byte array. Then i have to convert 8 byte array into hexadecimel string. Can you please help me in this. i'm struck up.
One way to do integer/byte array conversion is to use a union:
union {
long long l;
uint8_t b[sizeof(long long)];
} u;
u.l = mylonglong;
Then u.b[] contains the bytes, which can be accessed individually.
EDIT: Please note as pointed out by #NikolaiRuhe this use of union can lead to undefined behaviour, so it might be best to use memcpy() instead:
uint8_t b[sizeof(long long)];
memcpy(b, &mylonglong, sizeof(b));
If you want the hex string of the long long in native-endian order, then:
void hexChar(uint8_t b, char *out)
{
static const char *chars = "0123456789abcdef";
out[0] = chars[(b >> 4) & 0xf];
out[1] = chars[b & 0xf];
}
// Make sure outbuf is big enough
void hexChars(const uint8_t *buffer, size_t len, char *outbuf)
{
for (size_t i = 0; i < len; i++)
{
hexChar(buffer[i], outbuf);
outbuf += 2;
}
*outbuf = '\0';
}
and call it with:
char hex[32];
hexChars(u.b, sizeof(u.b), hex);
However if instead you want the hex value of the long long:
char hex[32];
sprintf(hex, "%llx", mylonglong);
would that do the trick ?
#include <stdio.h>
int main() {
long long int val = 0x424242;
char str_val[32];
snprintf(str_val, sizeof(str_val), "%#llx", val);
printf("Value : %s\n", str_val);
}

How do I convert a cdata structure into a lua string?

I'm in the middle of writing a small application that needs to read some complex binary messages in LuaJit.
I've been using the bit module and string.rep a lot. However, it's all very cumbersome. I'm new to using LuaJit and think there might be a much easier way using FFI.
In C I can declare a structure like this:
struct mystruct
{
uint32_t field1;
char field2[6];
uin64_t field3;
short field4;
} __attribute__(packed);
In reading LuaJit's FFI it seems you can declare
ffi.cdef[[
#pragma pack(1)
struct mystruct
{
uint32_t field1;
char field2[6];
uin64_t field3;
short field4;
};
]]
I can then create a mystruct and access the fields like this:
local ms = ffi.new("mystruct")
ms.field1 = 32;
// ... etc
But, how do I convert this back into a lua string?
I tried this, but it didn't seem to do what I wanted.
local s = tostring(ms)
and this:
local s = ffi.string(ms)
produces the following error "bad argument #1 to 'string' (cannot convert 'struct mystruct' to 'const char *')"
So I tried a cast:
local s = ffi.string(ffi.cast("char*", ms))
No error, but it looks wrong on the wire.
You have to explicitly specify the length when using ffi.string with a non-string-like parameter:
str = ffi.string(ptr [,len])
Creates an interned Lua string from the data pointed to by ptr.
If the optional argument len is missing, ptr is converted to a "char *" and the data is assumed to be zero-terminated. The length of the string is computed with strlen().
When running the following code, I get the expected (little endian) result:
ffi = require 'ffi'
ffi.cdef[[
typedef unsigned long uint32_t;
typedef unsigned long long uint64_t;
#pragma pack(1)
struct mystruct
{
uint32_t field1;
char field2[6];
uint64_t field3;
short field4;
};
]]
function string.tohex(str)
return (str:gsub('.', function (c)
return string.format('%02X', string.byte(c))
end))
end
ms = ffi.new('struct mystruct', 1, {2, 3, 4, 5, 6, 7}, 8, 9)
s = ffi.string(ms, ffi.sizeof(ms)) -- specify how long the byte sequence is
print(s:tohex()) --> 0100000002030405060708000000000000000900
Update: I know this is not a part of the original question, but I just learned this trick, and in order to be complete, here is a way to convert Lua string back to FFI cdata:
data = ffi.new('struct mystruct') -- create a new cdata
ffi.copy(data, s, ffi.sizeof(data)) -- fill it with data from Lua string 's'
print(data.field1, data.field4) --> 1 9
The previous has an error.
According to current luaffi implementation, you can cast it to void* . Use ffi.string(ffi.cast("void*",ms),ffi.sizeof(ms)) to do so.

C Programming: Linked Lists

I'm writing a program using linked list (such a nightmare).
Anyway, the purpose of the program is to enter 8 characters and have the program print the characters back out to you and also print the characters back out in reverse order, using linked lists of course.
I got this so far. There's a lot wrong with it (i think).
Problems are
When asking for characters from the user it should read in the amount of characters automatically without having to ask for how many characters
Also, when it it compiles it prints gibberish to the screen, for example I just ran it and it printed
¿r
(àõ($ê¿¿
a¿r
(àõ($ê¿¿
¿r
(àõ($ê¿¿
b¿r
(àõ($ê¿¿
Lots of help needed here. It would be so much appreciated!
Code of course
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define strsize 30
typedef struct member
{
int number;
char fname[strsize];
struct member *next;
}
RECORD;
RECORD* insert (RECORD *it);
RECORD* print(RECORD *it, int j);
int main (void)
{
int i, result;
RECORD *head, *p;
head=NULL;
printf("Enter the number of characters: ");
scanf("%d", &result);
for (i=1; i<=result; i++)
head=insert (head);
print (head, result);
return 0;
}
RECORD* insert (RECORD *it)
{
RECORD *cur, *q;
int num;
char junk;
char first[strsize];
printf("Enter a character:");
scanf("%c", &first);
cur=(RECORD *) malloc(sizeof(RECORD));
strcpy(cur->fname, first);
cur->next=NULL;
if (it==NULL)
it=cur;
else
{
q=it;
while (q->next!=NULL)
q=q->next;
q->next=cur;
}
return (it);
}
RECORD* print(RECORD *it, int j)
{
RECORD *cur;
cur=it;
int i;
for(i=1;i<=j;i++)
{
printf("%s \n", cur->fname);
cur=cur->next;
}
return;
}
You have:
in insert:
char first[strsize];
scanf("%c", &first); /* note the %c */
strcpy(cur->fname, first);
in print
printf("%s \n", cur->fname);
You should have %s instead of %c and therefore change &format to format in the argument list, as format itself represents the address of the location the string is to be stored.
So the scanf call should be like below
scanf("%s", first);
Another thing. If you have specified a return type in the print function then you should return something, or make it return nothing (declare return type as void). This will not pose any problem in this case although.
Read the warning messages which the compiler throws to you and you would see the compiler actually had answered your questions.
You need to do some redesigns i think. For example to traverse the linked list you do not need to counter 'j'. you can detect the list termination by inspecting if the next link is NULL or not.
Your question was to print the characters or strings in reverse, so you need to write some other print function than what you have wrote.

Resources