flat assembler
Message board for the users of flat assembler.
Index
> Linux > (solved)PIC WIP My attempt to call lib functions from my lib |
Author |
|
eilenbeb 13 Nov 2014, 02:09
The above will build if I comment out the 'call puts' line, and then I can get an objdump:
Code: libmisc.so: file format elf64-x86-64 libmisc.so architecture: i386:x86-64, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x0000000000000238 Program Header: LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21 filesz 0x0000000000000240 memsz 0x0000000000000240 flags r-x LOAD off 0x0000000000000240 vaddr 0x0000000000200240 paddr 0x0000000000200240 align 2**21 filesz 0x0000000000000110 memsz 0x0000000000000110 flags rw- DYNAMIC off 0x0000000000000240 vaddr 0x0000000000200240 paddr 0x0000000000200240 align 2**3 filesz 0x0000000000000110 memsz 0x0000000000000110 flags rw- Dynamic Section: NEEDED libc.so.6 SONAME libmisc.so AUXILIARY PIC HASH 0x00000000000000e8 STRTAB 0x00000000000001c0 SYMTAB 0x0000000000000118 STRSZ 0x0000000000000049 SYMENT 0x0000000000000018 VERNEED 0x0000000000000218 VERNEEDNUM 0x0000000000000001 VERSYM 0x000000000000020a Version References: required from libc.so.6: 0x09691a75 0x00 02 GLIBC_2.2.5 Sections: Idx Name Size VMA LMA File off Algn 0 .hash 00000030 00000000000000e8 00000000000000e8 000000e8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .dynsym 000000a8 0000000000000118 0000000000000118 00000118 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .dynstr 00000049 00000000000001c0 00000000000001c0 000001c0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.version 0000000e 000000000000020a 000000000000020a 0000020a 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.version_r 00000020 0000000000000218 0000000000000218 00000218 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .text 00000001 0000000000000238 0000000000000238 00000238 2**3 CONTENTS, ALLOC, LOAD, READONLY, CODE 6 .eh_frame 00000000 0000000000000240 0000000000000240 00000240 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .dynamic 00000110 0000000000200240 0000000000200240 00000240 2**3 CONTENTS, ALLOC, LOAD, DATA SYMBOL TABLE: 00000000000000e8 l d .hash 0000000000000000 .hash 0000000000000118 l d .dynsym 0000000000000000 .dynsym 00000000000001c0 l d .dynstr 0000000000000000 .dynstr 000000000000020a l d .gnu.version 0000000000000000 .gnu.version 0000000000000218 l d .gnu.version_r 0000000000000000 .gnu.version_r 0000000000000238 l d .text 0000000000000000 .text 0000000000000240 l d .eh_frame 0000000000000000 .eh_frame 0000000000200240 l d .dynamic 0000000000000000 .dynamic 0000000000200240 l O .dynamic 0000000000000000 _DYNAMIC 0000000000000000 l O .dynamic 0000000000000000 _GLOBAL_OFFSET_TABLE_ 0000000000000000 F *UND* 0000000000000000 puts@@GLIBC_2.2.5 0000000000200350 g .dynamic 0000000000000000 _edata 0000000000000238 g F .text 0000000000000000 szout 0000000000200350 g .dynamic 0000000000000000 _end 0000000000200350 g .dynamic 0000000000000000 __bss_start |
|||
13 Nov 2014, 02:09 |
|
eilenbeb 13 Nov 2014, 22:52
Partial success! here's the lib test code:
Code: format ELF64 ALIGN 8 public szout extrn puts ;; the PLT op was no-go ;; had to set w .text section '.text' writeable executable ;-------------------------- szout: lea rax,[puts] sub rax,4 call rax ;; string pointer still in rdi ret ;-------------------------- NOTE! 'puts' is actually pointing to libc-2.20.so::puts+4 !!! so there' still something wrong. by loading puts into rax and adjusting rax, things 'work'. '.text' had to be set writeable. That's what was fsck'ing up ld. I had no luck of any kind using the PLT operator. It was pointing someplace weird. Lastly, here's my build command. Code: #! /bin/bash fasm misc.fasm libmisc.o ld -m elf_x86_64 -shared -o libmisc.so -h libmisc.so libmisc.o -l:/lib/libc-2.20.so xterm -e sudo cp libmisc.so /lib/libmisc.so Note that the lib has to be 'installed' otherwise you need a funny command to launch a test program (wreaks havok on my debugger) I'll keep experimenting with this, but feel free to shout if you've any ideas for me. |
|||
13 Nov 2014, 22:52 |
|
eilenbeb 13 Nov 2014, 22:55
oops, here's the latest objdump
Code: libmisc.so: file format elf64-x86-64 libmisc.so architecture: i386:x86-64, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x0000000000000250 Program Header: LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21 filesz 0x0000000000000260 memsz 0x0000000000000260 flags r-x LOAD off 0x0000000000000260 vaddr 0x0000000000200260 paddr 0x0000000000200260 align 2**21 filesz 0x0000000000000140 memsz 0x0000000000000140 flags rw- DYNAMIC off 0x0000000000000260 vaddr 0x0000000000200260 paddr 0x0000000000200260 align 2**3 filesz 0x0000000000000140 memsz 0x0000000000000140 flags rw- Dynamic Section: NEEDED libc.so.6 SONAME libmisc.so HASH 0x00000000000000e8 STRTAB 0x00000000000001c0 SYMTAB 0x0000000000000118 STRSZ 0x0000000000000045 SYMENT 0x0000000000000018 RELA 0x0000000000000238 RELASZ 0x0000000000000018 RELAENT 0x0000000000000018 TEXTREL 0x0000000000000000 VERNEED 0x0000000000000218 VERNEEDNUM 0x0000000000000001 VERSYM 0x0000000000000206 Version References: required from libc.so.6: 0x09691a75 0x00 02 GLIBC_2.2.5 Sections: Idx Name Size VMA LMA File off Algn 0 .hash 00000030 00000000000000e8 00000000000000e8 000000e8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .dynsym 000000a8 0000000000000118 0000000000000118 00000118 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .dynstr 00000045 00000000000001c0 00000000000001c0 000001c0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.version 0000000e 0000000000000206 0000000000000206 00000206 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.version_r 00000020 0000000000000218 0000000000000218 00000218 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .rela.dyn 00000018 0000000000000238 0000000000000238 00000238 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .text 0000000e 0000000000000250 0000000000000250 00000250 2**3 CONTENTS, ALLOC, LOAD, READONLY, CODE 7 .eh_frame 00000000 0000000000000260 0000000000000260 00000260 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .dynamic 00000140 0000000000200260 0000000000200260 00000260 2**3 CONTENTS, ALLOC, LOAD, DATA SYMBOL TABLE: 00000000000000e8 l d .hash 0000000000000000 .hash 0000000000000118 l d .dynsym 0000000000000000 .dynsym 00000000000001c0 l d .dynstr 0000000000000000 .dynstr 0000000000000206 l d .gnu.version 0000000000000000 .gnu.version 0000000000000218 l d .gnu.version_r 0000000000000000 .gnu.version_r 0000000000000238 l d .rela.dyn 0000000000000000 .rela.dyn 0000000000000250 l d .text 0000000000000000 .text 0000000000000260 l d .eh_frame 0000000000000000 .eh_frame 0000000000200260 l d .dynamic 0000000000000000 .dynamic 0000000000200260 l O .dynamic 0000000000000000 _DYNAMIC 0000000000000000 l O .dynamic 0000000000000000 _GLOBAL_OFFSET_TABLE_ 0000000000000000 F *UND* 0000000000000000 puts@@GLIBC_2.2.5 00000000002003a0 g .dynamic 0000000000000000 _edata 0000000000000250 g F .text 0000000000000000 szout 00000000002003a0 g .dynamic 0000000000000000 _end 00000000002003a0 g .dynamic 0000000000000000 __bss_start |
|||
13 Nov 2014, 22:55 |
|
eilenbeb 13 Nov 2014, 23:59
Update: data access.
I've discovered that any data storage to be written/read must be in a '.data' section marked 'writeable'... UNLESS I comment out the '.text' declaration. Then I can define (and use) any data anywhere. Handy for per-function static or local non-stack storage. Anyone have any thoughts on this method? I'm now calling 2 libc funcs and both of their addresses are off by 4. Time to add another external lib and see what effect that has. EDIT: not worth a new post, but libc is a no-go. Need 2 seperate libs that DON'T require each other (or pull the other in). Delays: gotta find new exteral libs that don't require too much research. Again,feel free to pipe in. ATM I'm thinking about opengl + freeimage, just for a test. SRSLY anybody got any ideas why 'func' is off by 4? |
|||
13 Nov 2014, 23:59 |
|
evk1 14 Nov 2014, 18:47
Hi eilenbeb,
Some time ago I was working at the same problem, but my goal was to generate and use library with pure FASM. Unfortunately I was using ELF32, so I cannot define the problem exactly, but I think it is connected with RIP-relative addressing and ELF relocations for it. Could you provide an objdump for libmisc.o or at least its relocation section? Anyway you can use something like lea rax,[puts-4]. P.S. You have written, you have some experience in building ELF files from scratch, but in spite of this, you use ld. Why? _________________ Sorry for my English |
|||
14 Nov 2014, 18:47 |
|
eilenbeb 17 Nov 2014, 17:19
Hi. Sorry but I got busy and haven't done any more on this. Everything's on another system, I'll try to take a look later if I have time.
For some reason, the '-4' had no effect. Didn't understand that one, still at a loss. I'm only using ld until I can get a small, simple, working lib that references 2-4 funcs from 2 external libs. Then I'll start work on writing my own relocate headers. To put it simply, I don't know how yet. |
|||
17 Nov 2014, 17:19 |
|
eilenbeb 23 Nov 2014, 00:47
Ok. Sorry for dalays. I've still made no progress.
Since nothing is working right, I decided to re-simplify: here's my 'lib' Code: format ELF64 extrn puts public szout ;-------------------------- szout: call puts call plt puts ret ;-------------------------- When I run my test prog through the debugger, the 2 calls are the same. The plt operator seems to have no effect. I've been playing with every 'relocatable' and 'dynamic' thing I can find in the ld manpage, but nothing seems to make a difference. I can still 'lea rax,blah' then subtract 4. Works fine, if you call that working. I don't like my rax being tied up like that. Here's my ld: Code: ld -m elf_x86_64 -shared -o libmisc.so -h libmisc.so libmisc.o -l:/lib/libc-2.20.so So... I'm still at a total loss here. You (evk1) requested the objdump (-x?) frrom libmisc.o (??? NOT libmisc.so ???) Ok, objdump -x libmisc.o: Code: libmisc.o architecture: i386:x86-64, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x0000000000000000 Sections: Idx Name Size VMA LMA File off Algn 0 .flat 0000000b 0000000000000000 0000000000000000 00000040 2**3 CONTENTS, ALLOC, LOAD, RELOC, CODE SYMBOL TABLE: 0000000000000000 l d .flat 0000000000000000 .flat 0000000000000000 *UND* 0000000000000000 puts 0000000000000000 g F .flat 0000000000000000 szout RELOCATION RECORDS FOR [.flat]: OFFSET TYPE VALUE 0000000000000001 R_X86_64_PC32 puts 0000000000000006 R_X86_64_PC32 put objdump -x libmisc.so Code: libmisc.so: file format elf64-x86-64 libmisc.so architecture: i386:x86-64, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x0000000000000000 Program Header: LOAD off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21 filesz 0x0000000000000268 memsz 0x0000000000000268 flags r-- LOAD off 0x0000000000000268 vaddr 0x0000000000200268 paddr 0x0000000000200268 align 2**21 filesz 0x000000000000013b memsz 0x000000000000013b flags rwx DYNAMIC off 0x0000000000000268 vaddr 0x0000000000200268 paddr 0x0000000000200268 align 2**3 filesz 0x0000000000000130 memsz 0x0000000000000130 flags rw- Dynamic Section: NEEDED libc.so.6 SONAME libmisc.so HASH 0x00000000000000e8 STRTAB 0x00000000000001c0 SYMTAB 0x0000000000000118 STRSZ 0x0000000000000045 SYMENT 0x0000000000000018 RELA 0x0000000000000238 RELASZ 0x0000000000000030 RELAENT 0x0000000000000018 VERNEED 0x0000000000000218 VERNEEDNUM 0x0000000000000001 VERSYM 0x0000000000000206 Version References: required from libc.so.6: 0x09691a75 0x00 02 GLIBC_2.2.5 Sections: Idx Name Size VMA LMA File off Algn 0 .hash 00000030 00000000000000e8 00000000000000e8 000000e8 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .dynsym 000000a8 0000000000000118 0000000000000118 00000118 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .dynstr 00000045 00000000000001c0 00000000000001c0 000001c0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .gnu.version 0000000e 0000000000000206 0000000000000206 00000206 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .gnu.version_r 00000020 0000000000000218 0000000000000218 00000218 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .rela.dyn 00000030 0000000000000238 0000000000000238 00000238 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .eh_frame 00000000 0000000000000268 0000000000000268 00000268 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .dynamic 00000130 0000000000200268 0000000000200268 00000268 2**3 CONTENTS, ALLOC, LOAD, DATA 8 .flat 0000000b 0000000000200398 0000000000200398 00000398 2**3 CONTENTS, ALLOC, LOAD, CODE SYMBOL TABLE: 00000000000000e8 l d .hash 0000000000000000 .hash 0000000000000118 l d .dynsym 0000000000000000 .dynsym 00000000000001c0 l d .dynstr 0000000000000000 .dynstr 0000000000000206 l d .gnu.version 0000000000000000 .gnu.version 0000000000000218 l d .gnu.version_r 0000000000000000 .gnu.version_r 0000000000000238 l d .rela.dyn 0000000000000000 .rela.dyn 0000000000000268 l d .eh_frame 0000000000000000 .eh_frame 0000000000200268 l d .dynamic 0000000000000000 .dynamic 0000000000200398 l d .flat 0000000000000000 .flat 0000000000200268 l O .dynamic 0000000000000000 _DYNAMIC 0000000000000000 l O .dynamic 0000000000000000 _GLOBAL_OFFSET_TABLE_ 0000000000000000 F *UND* 0000000000000000 puts@@GLIBC_2.2.5 00000000002003a3 g .flat 0000000000000000 _edata 0000000000200398 g F .flat 0000000000000000 szout 00000000002003a8 g .flat 0000000000000000 _end 00000000002003a3 g .flat 0000000000000000 __bss_start I'm running out of ideas here. Any progress on your end? |
|||
23 Nov 2014, 00:47 |
|
evk1 25 Nov 2014, 20:53
Hi. Sorry for long delay. I have too little free time now.
Well, Of course your code is correct, but for unknown reason FASM generates incorrect object file for it. I didn't know why it is incorrect and in order to understand it I wrote 2 similar programs. Code: ;FASM code format ELF64 extrn puts public func1 section '.text' executable func1:call puts ret Code: ;gas code .text .globl func1 .type func1, @function func1: call puts ret .size func1, .-func1 The base difference between their object files is in relocation sections. FASM output: Code: Relocation section '.rela.text' at offset 0x46 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000001 000200000002 R_X86_64_PC32 0000000000000000 puts + 0 gas output: Code: Relocation section '.rela.text' at offset 0x320 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000001 000500000002 R_X86_64_PC32 0000000000000000 puts - 4 So to call a function gas intends to put an offset of function - 4 to instruction address field. I think it is required by processor. I haven't met such problems because such relocations usually appears only in relocatable files. Output libraries and programs usually use relocations only to put external function and data addresses to some their internal variables and then use these variables to make an indirect function call. I tried to use call puts-4, but readelf showed the same relocation section content: Code: Relocation section '.rela.text' at offset 0x46 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000001 000200000002 R_X86_64_PC32 0000000000000000 puts + 0 Consequently, FASM cannot correctly define an addend relocation field. I think it is due to the fact x86_64 ELF version uses RELA structure to define relocations instead of REL. The REL structure allows to place an addend directly at the relocatable address, but if you use RELA you have to place an addend at the special RELA structure field. This situation seems like FASM uses RELA but still places addend at the relocatable location. It is very strange. It seems like FASM has a serious bug, but I have no other ideas. _________________ Sorry for my English |
|||
25 Nov 2014, 20:53 |
|
eilenbeb 30 Nov 2014, 22:19
Fasm -is- creating the 'Addend' field, it's just filling it in with zeros. I just used a hex editor to modify that field, and now 'call plt puts' works as expected.
My reloc table is of type .rela.flat (at the moment) But i've seen other rela types during my experiments. Code: readelf -a ./libmisc.o -snip- Relocation section '.rela.flat' at offset 0x4c contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000002 000200000002 R_X86_64_PC32 0000000000000000 puts - 4 000000000007 000200000002 R_X86_64_PC32 0000000000000000 puts + 0 -snip- It shouldn't be too hard to write a 'fixup' program to patch the .o file before passing it to ld. I just gotta learn how to read the headers better so I can -find- the '.rela.flat' table, heh. -edit- Just wrote a 'fixup' prog that adjusts the Addend field in the .o file before running ld. Seems to be working, but I know it isn't 'correct' yet. I need to get ahold of the ELF specs and make sure I'm not doing anything hack-ish. My little test lib now exports two funcs and imports 5 from 2 external libs. All the calls now go where they're supposed to. |
|||
30 Nov 2014, 22:19 |
|
Tomasz Grysztar 01 Dec 2014, 10:55
Yes, there is a serious bug here. I think I already knew about it but it got forgotten for some reason. I'm fixing it right now. Please try the 1.71.28 version and let me know if this solves the problem.
|
|||
01 Dec 2014, 10:55 |
|
eilenbeb 01 Dec 2014, 22:25
Hey Tomasz. Sorry but I just got busy again. Might be a couple of days before I can test v28.
-edit- Ok, I tested v28 (in 64bit only) and it appears to be working. Nice job. Marking as solved. |
|||
01 Dec 2014, 22:25 |
|
Tomasz Grysztar 07 Dec 2014, 13:15
The correction was still incomplete, version 1.71.30 has the final fix.
|
|||
07 Dec 2014, 13:15 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.