I have made a function in C which is pretty straightforward, it uses strlen() from <string.h> to return the length of a char* variable:
int length(char *str) {
return strlen(str);
}
Here is the corresponding x86_64 assembly from objdump -M intel -d a.out:
00000000000011a8 <length>:
11a8: f3 0f 1e fa endbr64
11ac: 55 push rbp
11ad: 48 89 e5 mov rbp,rsp
11b0: 48 83 ec 10 sub rsp,0x10
11b4: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi
11b8: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
11bc: 48 89 c7 mov rdi,rax
11bf: e8 ac fe ff ff call 1070 <strlen@plt>
11c4: c9 leave
11c5: c3 ret
Here is my current understanding of the code (please correct me if anything seems wrong):
00000000000011a8 <length>:
11a8: f3 0f 1e fa endbr64
11ac: 55 push rbp // stack setup, old rbp of previous frame pushed
11ad: 48 89 e5 mov rbp,rsp // rbp and rsp point to same place
11b0: 48 83 ec 10 sub rsp,0x10 // space is made for arguments
11b4: 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi // rdi stores argument and is moved into the space made on the line 11b0
11b8: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8] // value at memory address rbp-0x8 aka argument is stored in rax
11bc: 48 89 c7 mov rdi,rax // move the value into rdi for function call
11bf: e8 ac fe ff ff call 1070 <strlen@plt> // strlen() is called
11c4: c9 leave // stack clear up
11c5: c3 ret // return address popped and control flow resumes
If anything above is incorrect please correct me, secondly how does call 1070 <strlen@plt> return a value? because the strlen() function returns the length of a string and i would have thought that something would have been moved into the rax register (which i believe is commonly used for return values). But nothing is moved into rax and it does not show a value returned in the assembly.
Lastly here is the code at address 1070 (from call 1070 strlen@plt)
0000000000001070 <strlen@plt>:
1070: f3 0f 1e fa endbr64
1074: f2 ff 25 45 2f 00 00 bnd jmp QWORD PTR [rip 0x2f45] # 3fc0 <strlen@GLIBC_2.2.5>
107b: 0f 1f 44 00 00 nop DWORD PTR [rax rax*1 0x0]
CodePudding user response:
how does call 1070 strlen@plt return a value?
The strlen puts its result into rax register, which conveniently is also where your length() function should put its return value.
Under optimization your length() could be compiled into a single instruction: jmp strlen -- the parameter is already in rdi, and the return value will be in rax.
P.S.
Lastly here is the code at address 1070
That isn't the actual code of strlen. This is a "PLT jump stub". To understand what that is, you could read this blog post.
Also, from that small address, you can see this is a PIE executable: those are just offsets from the image base address; the runtime address will be something like 0x55...
