public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* Accessing String Table Indexes for .rodata
@ 2018-08-20 16:16 Henry C
  2018-08-30 19:54 ` Mark Wielaard
  0 siblings, 1 reply; 6+ messages in thread
From: Henry C @ 2018-08-20 16:16 UTC (permalink / raw)
  To: elfutils-devel

Hi,

I have a sample code like this:
#include <cstdio>

void myprintf(const char* ptr) {
        printf("%p\n", ptr);
}

int main() {
        myprintf("hello world");
        myprintf("\0\0");
        myprintf("ab\0cde");
}

I would like to access the .rodata by using elf.h.  Someone told me
this is the right place to ask how.  If not, please do let me know.

I am able to access the string table for .rodata section by calling my function:
void print_rodata_table64(int32_t fd,
Elf64_Ehdr eh,
Elf64_Shdr sh_table[],
uint32_t indexToRodata)
{
char* sh_str; /* section-header string-table is also a section. */

/* Read section-header string-table */
        Elf64_Shdr& sh = sh_table[indexToRodata];
sh_str = malloc(sh.sh_size);
        lseek(fd, (off_t)sh.sh_offset, SEEK_SET);
        read(fd, (void *)sh_str, sh.sh_size);
for (uint64_t i = 0; i < sh.sh_size; i++) {
printf("data[%lu]=%u|%c\n", i, (uint32_t)sh_str[i], sh_str[i]);
}
}

Tho, I have no clue how to get the index to each of the string in the
string table above.

Any sample code or pointer is highly appreciated!

And one more related question is that I noticed the virtual memory
addresses of the string literals are same as the offsets to the
(executable) file.  Is it intended?  Guaranteed?


Thanks!

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Accessing String Table Indexes for .rodata
  2018-08-20 16:16 Accessing String Table Indexes for .rodata Henry C
@ 2018-08-30 19:54 ` Mark Wielaard
  2018-08-31 11:07   ` Henry C
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Wielaard @ 2018-08-30 19:54 UTC (permalink / raw)
  To: Henry C; +Cc: elfutils-devel

On Tue, Aug 21, 2018 at 12:16:09AM +0800, Henry C wrote:
> Tho, I have no clue how to get the index to each of the string in the
> string table above.

The .rodata section isn't just a simple ELF string table.
Otherwise you could use elf_strptr (see libelf.h) to index through them.
But .rodata also contains other read only data. There is no simple
ELF based index for just the strings.

> And one more related question is that I noticed the virtual memory
> addresses of the string literals are same as the offsets to the
> (executable) file.  Is it intended?  Guaranteed?

If you mean that the sh_offset and sh_addr are the same then that
not guaranteed. The mapping from file offset to addresses for allocated
sections is given by the program headers. You can see how they are
mapped exactly using eu-readelf -l.

Cheers,

Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Accessing String Table Indexes for .rodata
  2018-08-30 19:54 ` Mark Wielaard
@ 2018-08-31 11:07   ` Henry C
  2018-08-31 11:33     ` Mark Wielaard
  0 siblings, 1 reply; 6+ messages in thread
From: Henry C @ 2018-08-31 11:07 UTC (permalink / raw)
  To: mark; +Cc: elfutils-devel

Thanks for replying.

I mean for example,
void myprintf(const char* ptr) {
        printf("%p\n", ptr);
}

int main() {
        myprintf("hello world");
}

Let's say the output is 0x403DE.

Does it mean that Elf64_Shdr::sh_addr of the string table (of .rodata)
+ the offset of "hello word" within the string table is guaranteed to
be the virtual address 0x403DE?  As I am not sure whether virtual
memory addresses of all string literals are defined/calculated when
ELF is created.

Thanks!

Cheers

On Fri, Aug 31, 2018 at 3:54 AM Mark Wielaard <mark@klomp.org> wrote:
>
> On Tue, Aug 21, 2018 at 12:16:09AM +0800, Henry C wrote:
> > Tho, I have no clue how to get the index to each of the string in the
> > string table above.
>
> The .rodata section isn't just a simple ELF string table.
> Otherwise you could use elf_strptr (see libelf.h) to index through them.
> But .rodata also contains other read only data. There is no simple
> ELF based index for just the strings.
>
> > And one more related question is that I noticed the virtual memory
> > addresses of the string literals are same as the offsets to the
> > (executable) file.  Is it intended?  Guaranteed?
>
> If you mean that the sh_offset and sh_addr are the same then that
> not guaranteed. The mapping from file offset to addresses for allocated
> sections is given by the program headers. You can see how they are
> mapped exactly using eu-readelf -l.
>
> Cheers,
>
> Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Accessing String Table Indexes for .rodata
  2018-08-31 11:07   ` Henry C
@ 2018-08-31 11:33     ` Mark Wielaard
  2018-08-31 12:35       ` Henry C
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Wielaard @ 2018-08-31 11:33 UTC (permalink / raw)
  To: Henry C; +Cc: elfutils-devel

On Fri, 2018-08-31 at 19:07 +0800, Henry C wrote:
> Thanks for replying.
> 
> I mean for example,
> void myprintf(const char* ptr) {
>         printf("%p\n", ptr);
> }
> 
> int main() {
>         myprintf("hello world");
> }
> 
> Let's say the output is 0x403DE.
> 
> Does it mean that Elf64_Shdr::sh_addr of the string table (of
> .rodata)
> + the offset of "hello word" within the string table is guaranteed to
> be the virtual address 0x403DE?  As I am not sure whether virtual
> memory addresses of all string literals are defined/calculated when
> ELF is created.

No, that is not guaranteed. How data in an ELF file is mapped into
memory is determined by the program headers (not the section headers).
See also the picture showing the different ELF file data views in https
://en.wikipedia.org/wiki/Executable_and_Linkable_Format

Cheers,

Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Accessing String Table Indexes for .rodata
  2018-08-31 11:33     ` Mark Wielaard
@ 2018-08-31 12:35       ` Henry C
  2018-08-31 12:42         ` Mark Wielaard
  0 siblings, 1 reply; 6+ messages in thread
From: Henry C @ 2018-08-31 12:35 UTC (permalink / raw)
  To: mark; +Cc: elfutils-devel

Hi Mark,

I just dumped out my executable (code was in my very first email):
$ eu-readelf -l myexec

Program Headers:
  Type           Offset   VirtAddr           PhysAddr
FileSiz  MemSiz   Flg Align
  PHDR           0x000040 0x0000000000400040 0x0000000000400040
0x0001f8 0x0001f8 R E 0x8
  INTERP         0x000238 0x0000000000400238 0x0000000000400238
0x00001c 0x00001c R   0x1
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x000000 0x0000000000400000 0x0000000000400000
0x00079c 0x00079c R E 0x200000
  LOAD           0x000de8 0x0000000000600de8 0x0000000000600de8
0x000247 0x000248 RW  0x200000
  DYNAMIC        0x000df8 0x0000000000600df8 0x0000000000600df8
0x000200 0x000200 RW  0x8
  NOTE           0x000254 0x0000000000400254 0x0000000000400254
0x000044 0x000044 R   0x4
  GNU_EH_FRAME   0x00063c 0x000000000040063c 0x000000000040063c
0x000044 0x000044 R   0x4
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000
0x000000 0x000000 RW  0x10
  GNU_RELRO      0x000de8 0x0000000000600de8 0x0000000000600de8
0x000218 0x000218 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00
   01      [RO: .interp]
   02      [RO: .interp .note.ABI-tag .note.gnu.build-id .gnu.hash
.dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init
.plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame]
   03      [RELRO: .init_array .fini_array .dynamic .got] .got.plt .data .bss
   04      [RELRO: .dynamic]
   05      [RO: .note.ABI-tag .note.gnu.build-id]
   06      [RO: .eh_frame_hdr]
   07
   08      [RELRO: .init_array .fini_array .dynamic .got]

By looking at the output and the wiki link, the program headers do
contain virtual addresses but nothing explicit about .rodata.  How can
I use libelf to figure the correct virtual memory address to "hello
world"?

But if I print out Elf64_Shdr::sh_addr (.rodata section header) +
offset to "hello world" in .rodata, I do see the output matches the
output of printf("%p\n", "hello world");

As you mentioned, it is not guaranteed, I wonder under what situation
Elf64_Shdr::sh_addr won't represent the virtual address of the
beginning of .rodata section.

Thanks in advance!
On Fri, Aug 31, 2018 at 7:33 PM Mark Wielaard <mark@klomp.org> wrote:
>
> On Fri, 2018-08-31 at 19:07 +0800, Henry C wrote:
> > Thanks for replying.
> >
> > I mean for example,
> > void myprintf(const char* ptr) {
> >         printf("%p\n", ptr);
> > }
> >
> > int main() {
> >         myprintf("hello world");
> > }
> >
> > Let's say the output is 0x403DE.
> >
> > Does it mean that Elf64_Shdr::sh_addr of the string table (of
> > .rodata)
> > + the offset of "hello word" within the string table is guaranteed to
> > be the virtual address 0x403DE?  As I am not sure whether virtual
> > memory addresses of all string literals are defined/calculated when
> > ELF is created.
>
> No, that is not guaranteed. How data in an ELF file is mapped into
> memory is determined by the program headers (not the section headers).
> See also the picture showing the different ELF file data views in https
> ://en.wikipedia.org/wiki/Executable_and_Linkable_Format
>
> Cheers,
>
> Mark

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Accessing String Table Indexes for .rodata
  2018-08-31 12:35       ` Henry C
@ 2018-08-31 12:42         ` Mark Wielaard
  0 siblings, 0 replies; 6+ messages in thread
From: Mark Wielaard @ 2018-08-31 12:42 UTC (permalink / raw)
  To: Henry C; +Cc: elfutils-devel

On Fri, 2018-08-31 at 20:35 +0800, Henry C wrote:
> As you mentioned, it is not guaranteed, I wonder under what situation
> Elf64_Shdr::sh_addr won't represent the virtual address of the
> beginning of .rodata section.

Try creating a shared library or compile your application with -pie to
make an ELF executable that isn't mapped at a fixed address. Also not
all ELF files will have a section table, some might only have program
headers. In that case you cannot even locate the .rodata section since
it will just be part of some segment.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-08-31 12:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-20 16:16 Accessing String Table Indexes for .rodata Henry C
2018-08-30 19:54 ` Mark Wielaard
2018-08-31 11:07   ` Henry C
2018-08-31 11:33     ` Mark Wielaard
2018-08-31 12:35       ` Henry C
2018-08-31 12:42         ` Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).