0

As part of an assignment, I have to deal with three structs. There is some larger table within a file, FileHeader, that is made up of SectionHeader structs. Hdr is made up of an array of these structs laid out in contiguous memory. As a result, I should be able to access the array by typecasting the location of the table in memory.

typedef struct {
    unsigned int offset; // offset in bytes from start of file to section headers
    unsigned short headers; // count of section headers in table
} FileHeader;

typedef struct {
    unsigned int name;
    unsigned int type;        
} SectionHeader;

I am supposed to: Use the offset and headers fields from the FileHeader (hdr) to identify the location and length of the section header table. I have assumed the start of the file is &hdr.

So I did this, but it is giving me a seg-fault. What is the proper way to access this array?

    int header_location = hdr.offset;
    int header_length = hdr.headers;

    SectionHeader *sec_hdrs = (SectionHeader *) &hdr + header_location;

    SectionHeader sec_hdr;

    for (int i = 0; i < header_length; i++) {

            sec_hdr = sec_hdrs[i];
            if (sec_hdr.type == SHT_SYMTAB) break;
    }
  • @haccks Sorry, my mistake. Have fixed it now. –  Aug 04 '14 at 14:30
  • You're indexing into `sec_hdrs`, but it doesn't seem to be an (allocated) array. I don't think that's going to work. –  Aug 04 '14 at 14:31
  • @Evert - Yes, on other questions here, I have seen that you might have to malloc first. But I do not understand why that is necessary if you have a pointer to the array if you know that it is in contiguous memory, and also how to do this. –  Aug 04 '14 at 14:32
  • Draw it on a paper: use little cells as memory blocks, appropriately sized (int, short); you'll quickly see that what you are doing in `sec_hdrs[i]` doesn't make sense. –  Aug 04 '14 at 14:34
  • Fair enough, but this still does not answer how to access the array. According to the spec, I should be able to typecast the location of the table in memory so that I can access it. –  Aug 04 '14 at 14:36
  • Be aware that structs can have padding (cf. http://stackoverflow.com/questions/4306186/structure-padding-and-structure-packing) and/or lead to unaligned memory access (cf. http://lwn.net/Articles/260832/ or http://stackoverflow.com/questions/1063809/aligned-and-unaligned-memory-accesses). – king_nak Aug 04 '14 at 14:36
  • Is `FileHeader` indeed the start of the file? Otherwise `&hrd + header_location` doesn't make sense. –  Aug 04 '14 at 14:44
  • Yes, it is. What was the initial point you explained about the malloc? –  Aug 04 '14 at 14:52

3 Answers3

2

Try this: ElfSectionHeader *sec_hdrs = (ElfSectionHeader *)((unsigned char *) &hdr + header_location);

Your orinal code &hdr + header_location would offset the pointer by sizeof(hdr) * header_location which is not your intention.

vijairaj
  • 310
  • 3
  • 10
  • Why would it offset by size? –  Aug 04 '14 at 14:55
  • That's how [pointer arithmetic works](http://stackoverflow.com/questions/3523145/pointer-arithmetic-for-void-pointer-in-c). Every time you increment a pointer the address is offset by the sizeof the underlying type. – vijairaj Aug 04 '14 at 14:59
  • This is a very valid point and it will be worth your time to study pointer arithmetic if it doesn't make sense. – Toby Liu Aug 04 '14 at 16:06
0

You declared sec_hdrs as a pointer to SectionHeader. It is not an array and it can't be indexed. Your compiler should raise a warning.

Try this:

SectionHeader hdrs[header_length]
int header_location = hdrs[0].offset;
int header_length = hdrs[0].headers;

SectionHeader *sec_hdrs = hdrs + header_location;

SectionHeader sec_hdr;

for (int i = 0; i < header_length; i++) {
     sec_hdr = sec_hdrs[i];
     if (sec_hdr.type == SHT_SYMTAB) break;
}
haccks
  • 104,019
  • 25
  • 176
  • 264
  • So how do I treat this as an array (the second part of the above question?) –  Aug 04 '14 at 14:33
  • `SectionHeader` doesn't contain `.offset` or `.headers` (first 3 lines); `FileHeader` does, but that's not an array. –  Aug 04 '14 at 14:45
  • So, to clarify, the array starts at the offset from the beginning of the file (so beginning of the file + offset) should give the location where the array starts. This is why I did &hdr + offset to find it. –  Aug 04 '14 at 14:46
0

Here is a visualization of the memory with an initial offset followed by SectionHeader's placed in contiguous memory.

header_location | sizeof(SectionHeader)| sizeof(SectionHeader) | sizeof(SectionHeader)

vijairaj makes a very valid point about a possible bug in your code.

Your original code &hdr + header_location would offset the pointer by sizeof(hdr) * header_location which is not your intention.

This is a valid diagnosis and you should investigate how pointer arithmetic works. We increment the address by the size of its type. Once you are sure that *sec_hdrs is pointing to the correct place, rerun your program. If the segfault persists, try my next piece of debugging advice.

Yes, on other questions here, I have seen that you might have to malloc first. But I do not understand why that is necessary if you have a pointer to the array if you know that it is in contiguous memory, and also how to do this.

Just because we know something is in contiguous memory does not mean it is safe from being overwritten or reused by our program. That is the point of malloc - to protect certain blocks of memory from being overwritten. If you access unallocated memory, you run the risk of accessing sensitive data, overwriting program-dependent data, or storing data that will get overwritten. This is why a segfault will occur and this is why you need to malloc.

Ensure that you malloc enough space:

 malloc(header_location + header_length * sizeof(SectionHeader))

This line of code is saying, "Please allocate contiguous memory for one offset and n SectionHeader's". The malloc call will return a pointer to the start of that memory block (&hdr) and then you may access anything within that block of memory.

Perhaps include the code that is providing you with &hdr? Hope this is helpful!

Toby Liu
  • 1,267
  • 9
  • 14
  • One last question, I think one of my problems may have to do with the file that is being read in. So, I have another function that is provided that reads in all the files information and returns data. Should I be using the instead of hdr? –  Aug 04 '14 at 15:51
  • Hello, I was wrong to qualify your code as correct. vijairaj actually hits a very good point: depending on the pointer type of hdr, your offset calculation may be off. As for your file reading function - this seems quite implementation specific. I am only able to answer your question in the scope you've provided us. – Toby Liu Aug 04 '14 at 15:56