``` (gdb) info address System_Console_ReadLine Symbol "System_Console_ReadLine" is a function at address 0x7f9a3ce60f50. ``` ok, time to look for something close to `0x7f9a3ce60f50` on the stack as a return address.
(gdb) x/300xg $rsp
0x7ffd84d06930: 0x0000000000000000      0x0000000000603f21
0x7ffd84d06940: 0x0000000002106908      0x32bfbbdd7b4d2300
0x7ffd84d06950: 0x0000000000000004      0x0000000000000000
0x7ffd84d06960: 0x00007f9a3ec0a150      0x0000000000000400
0x7ffd84d06970: 0x00007ffd84d06a80      0x00000000005d7c20
0x7ffd84d06980: 0x000000003cd61c3d      0x32bfbbdd7b4d2300
0x7ffd84d06990: 0x0000000000000000      0x00007ffd84d06a60
0x7ffd84d069a0: 0x00007f9a3ec0a150      0x0000000000000000
0x7ffd84d069b0: 0x0000000000000400      0x0000000041951b2a
0x7ffd84d069c0: 0x0000000000000000      0x00007f9a3ec09ff8
0x7ffd84d069d0: 0x00007f9a3ec0a150      0x0000000000000000
0x7ffd84d069e0: 0x0000000000000400      0x00000000020b49b0
0x7ffd84d069f0: 0x00007f9a3ec0a150      0x00007ffd84d06a60
0x7ffd84d06a00: 0x00007ffd84d069c0      0x00007f9a3cd61b91
0x7ffd84d06a10: 0x00007ffd84d06a80      0x0000000000000400
0x7ffd84d06a20: 0x0000000000000000      0x00007f9a3ec0a150
0x7ffd84d06a30: 0x00007f9a3ec0a068      0x00007f9a3ec0a118
0x7ffd84d06a40: 0x00007f9a3ec0a170      0x0000000000000007
0x7ffd84d06a50: 0x00007f9a3ec0a501      0x0000000000000400
0x7ffd84d06a60: 0x0000000000000400      0x00007f9a3cd60348
0x7ffd84d06a70: 0x0000000000000000      0x0000000000000400
0x7ffd84d06a80: 0x00007f9a00000000      0x00007f9a3ec09ff8
0x7ffd84d06a90: 0x00007f9a3ec0a068      0x00007f9a3ec0a150
0x7ffd84d06aa0: 0x0000000000000400      0x00007f9a3cd5e517
0x7ffd84d06ab0: 0x0000000000000400      0x00007ffd84d06d00
0x7ffd84d06ac0: 0x00007f9a3ec09ff8      0x00007f9a3ec0a150
0x7ffd84d06ad0: 0x0000000000000000      0x0000000000000400
0x7ffd84d06ae0: 0x0000000000000400      0x00007f9a3cd5e382
0x7ffd84d06af0: 0x00000000020f1e30      0x0000000000000000
0x7ffd84d06b00: 0x00007f9a3ec00628      0x00007ffd84d06c38
0x7ffd84d06b10: 0x00007f9a3ec0a0b0      0x0000000000000000
0x7ffd84d06b20: 0x00007f9a3ec00628      0x00007f9a3cbcddc5
0x7ffd84d06b30: 0x00000000020f1e30      0x00007ffd84d06d00
0x7ffd84d06b40: 0x0000000000000000      0x00007f9a3ec00628
0x7ffd84d06b50: 0x00007ffd84d06c38      0x00007f9a3ec0a0b0
0x7ffd84d06b60: 0x00000000020f1e30      0x00007f9a3cbccc44
0x7ffd84d06b70: 0x00000000020f1e30      0x0000000000000000
0x7ffd84d06b80: 0x00007f9a3ec00628      0x00007f9a3ec00628
0x7ffd84d06b90: 0x00007ffd84d06c38      0x00007f9a00000000
0x7ffd84d06ba0: 0x00007ffd84d06b60      0x00007f9a3ce78294
0x7ffd84d06bb0: 0x0000000000000000      0x0000000000000004
0x7ffd84d06bc0: 0x00007f9a3ec272f8      0x00007ffd84d06c28
0x7ffd84d06bd0: 0x00007f9a3ec08328      0x00007f9a3cc6f872
0x7ffd84d06be0: 0x00007f9a3ec272f8      0x00007f9a3ce78a12
0x7ffd84d06bf0: 0x00000000020f1e30      0x00007ffd84d06fe0
0x7ffd84d06c00: 0x0000000000000000      0x00007f9a3ec08328
0x7ffd84d06c10: 0x00007f9a3ec08328      0x0000000041952328
0x7ffd84d06c20: 0x0000000041952315      0x0000000000000000
0x7ffd84d06c30: 0x00007f9a00000000      0x00007f9a3ec07800
0x7ffd84d06c40: 0x00007f9a3ec272f8      0x00007f9a3ce628c4
0x7ffd84d06c50: 0x00007f9a3ec08328      0x00007f9a3ce61027 <--- this is our winner
0x7ffd84d06c60: 0x000000004194fe50      0x00007ffd84d06fe0
0x7ffd84d06c70: 0x0000000000000005      0x000000004194fdca
0x7ffd84d06c80: 0x000000004194fd50      0x000000004194fd50
0x7ffd84d06c90: 0x000000004194fd50      0x000000004194ff19
0x7ffd84d06ca0: 0x000000000000001f      0x0000000000000000
0x7ffd84d06cb0: 0x31c01d4184d06f90      0x0000000000000000
0x7ffd84d06cc0: 0x0000000000000000      0x32bfbbdd7b4d2300
0x7ffd84d06cd0: 0x00000000020908b0      0x00000000020f1e30
0x7ffd84d06ce0: 0x00007ffd84d06f90      0x000000004194fe50
0x7ffd84d06cf0: 0x0000000002091d30      0x0000000000000000
0x7ffd84d06d00: 0x00007ffd84d06f90      0x00000000004266b8
0x7ffd84d06d10: 0x00000000020ed240      0x000000000208df90
0x7ffd84d06d20: 0x0000000000000000      0x00000000020f9c00
0x7ffd84d06d30: 0x0000000000000025      0x0000000000000000
0x7ffd84d06d40: 0x0000000000000000      0x0000000000000000
0x7ffd84d06d50: 0x000000000209bfa8      0x00007f9a00000000
0x7ffd84d06d60: 0x0000000000000000      0x00007f9a3f733b20
0x7ffd84d06d70: 0x0000000000000026      0x0000000000000025
0x7ffd84d06d80: 0x00007ffd84d06df4      0x00007f9a3f749c89
0x7ffd84d06d90: 0x0000000000000000      0x00000000006366fe
0x7ffd84d06da0: 0x00007f9a401b4130      0x00000000020f1d80
0x7ffd84d06db0: 0x00007ffd84d071f0      0x00007f9a3f3f398c
0x7ffd84d06dc0: 0x00007ffd84d071f0      0x00007f9a3f3f35d4
0x7ffd84d06dd0: 0x00000000020af860      0x0000000000632060
0x7ffd84d06de0: 0x00000000020f1d80      0x0000000000000000
0x7ffd84d06df0: 0x0000000000000000      0x000000000208df90
0x7ffd84d06e00: 0x00000000020f1d80      0x00000000020f1d80
0x7ffd84d06e10: 0x00007f9a401b4130      0x00000000020f1d80
0x7ffd84d06e20: 0x00007ffd84d071f0      0x00007f9a3f3f398c
0x7ffd84d06e30: 0x0000000000000000      0x32bfbbdd7b4d2300
0x7ffd84d06e40: 0x00007ffd84d06eb0      0x000000000054537c
0x7ffd84d06e50: 0x00000000020f1d80      0x000000000208df90
0x7ffd84d06e60: 0x00000000020f1d80      0x00000000020f1d80
0x7ffd84d06e70: 0x00007f9a401b4130      0x32bfbbdd7b4d2300
0x7ffd84d06e80: 0x0000000000000000      0x0000000002091d30
0x7ffd84d06e90: 0x0000000002091d30      0x0000000000000000
0x7ffd84d06ea0: 0x00007f9a401b4130      0x00000000020f1d80
0x7ffd84d06eb0: 0x00007ffd84d071f0      0x00000000005452d9
0x7ffd84d06ec0: 0x0000000000000000      0x0000000002091d30
0x7ffd84d06ed0: 0x00000000020911c0      0x0000000002091350
0x7ffd84d06ee0: 0x0000000000000040      0x00000000020f1d80
0x7ffd84d06ef0: 0x00007ffd84d071f0      0x000000000055fec6
0x7ffd84d06f00: 0x0000000000000040      0x0000000002091350
0x7ffd84d06f10: 0x00007f9a3ec00388      0x32bfbbdd7b4d2300
0x7ffd84d06f20: 0x00007f9a401b4130      0x0000000002091d30
0x7ffd84d06f30: 0x00000000020911c0      0x0000000000000000
0x7ffd84d06f40: 0x00007f9a401b4130      0x00000000005b910a
0x7ffd84d06f50: 0x000000000208df90      0x32bfbbdd7b4d2300
0x7ffd84d06f60: 0x00007f9a401b4130      0x0000000002091d30
0x7ffd84d06f70: 0x00007ffd84d06fe0      0x0000000000000000
0x7ffd84d06f80: 0x00000000020f1d80      0x00007ffd84d071f0
0x7ffd84d06f90: 0x0000000000000000      0x00000000005ac68d
0x7ffd84d06fa0: 0x000000000208df90      0x0000000002091d30
0x7ffd84d06fb0: 0x0000000000000000      0x0000000000000000
0x7ffd84d06fc0: 0x00007f9a401b4130      0x00000000005ae9cc
0x7ffd84d06fd0: 0x000000000208df90      0x0000000000000000
0x7ffd84d06fe0: 0x00007f9a3ec00328      0x32bfbbdd7b4d2300
0x7ffd84d06ff0: 0x00007ffd84d07484      0x000000000208df90
0x7ffd84d07000: 0x0000000000000001      0x00000000020ed390
0x7ffd84d07010: 0x0000000000000000      0x0000000000476967
0x7ffd84d07020: 0x0000000000000000      0x00000000161169ff
0x7ffd84d07030: 0x0000000000000000      0x0000000000000000
0x7ffd84d07040: 0x0000000000000000      0x0000000000000000
0x7ffd84d07050: 0x0000000000000004      0x0000000000000000
0x7ffd84d07060: 0x0000000000000000      0x0000000000000000
0x7ffd84d07070: 0x0000000000000000      0x0000000000000000
0x7ffd84d07080: 0x0000000000000002      0x0000000100000001
0x7ffd84d07090: 0x0000000000639710      0x000000000208df90
0x7ffd84d070a0: 0x00007ffd84d071e0      0x0000000000000002
0x7ffd84d070b0: 0x0000000000000000      0x0000000000422c0e
0x7ffd84d070c0: 0x0000000000000001      0x32bfbbdd7b4d2300
0x7ffd84d070d0: 0x0000000000000000      0x0000000000000000
0x7ffd84d070e0: 0x0000000000639710      0x0000000000422e50
0x7ffd84d070f0: 0x00007ffd84d071e0      0x0000000000000000
0x7ffd84d07100: 0x0000000000000000      0x00007f9a3f390830
0x7ffd84d07110: 0x0000000000000000      0x00007ffd84d071e8
0x7ffd84d07120: 0x0000000240290ca0      0x0000000000422be0
0x7ffd84d07130: 0x0000000000000000      0x42f8e52f22cfd5b5
0x7ffd84d07140: 0x0000000000422e50      0x00007ffd84d071e0
0x7ffd84d07150: 0x0000000000000000      0x0000000000000000
0x7ffd84d07160: 0xbd03ec48eecfd5b5      0xbdcc9b9a033fd5b5
0x7ffd84d07170: 0x00007ffd00000000      0x0000000000000000
0x7ffd84d07180: 0x0000000000000000      0x0000000000639780
0x7ffd84d07190: 0x00007f9a4007b8e0      0x00007f9a4007b5fb
0x7ffd84d071a0: 0x0000000000000000      0x0000000000000000
0x7ffd84d071b0: 0x0000000000422e50      0x00007ffd84d071e0
0x7ffd84d071c0: 0x0000000000000000      0x0000000000422e79
0x7ffd84d071d0: 0x00007ffd84d071d8      0x000000000000001c
0x7ffd84d071e0: 0x0000000000000002      0x00007ffd84d0747f
0x7ffd84d071f0: 0x00007ffd84d07484      0x0000000000000000
0x7ffd84d07200: 0x00007ffd84d0748e      0x00007ffd84d07499
0x7ffd84d07210: 0x00007ffd84d074aa      0x00007ffd84d074bd
0x7ffd84d07220: 0x00007ffd84d074da      0x00007ffd84d074eb
0x7ffd84d07230: 0x00007ffd84d074fb      0x00007ffd84d07507
0x7ffd84d07240: 0x00007ffd84d07519      0x00007ffd84d07529
0x7ffd84d07250: 0x00007ffd84d07536      0x00007ffd84d07565
0x7ffd84d07260: 0x00007ffd84d07aed      0x00007ffd84d07b1c
0x7ffd84d07270: 0x00007ffd84d07b33      0x00007ffd84d07e50
0x7ffd84d07280: 0x00007ffd84d07e71      0x00007ffd84d07e81
0x7ffd84d06c58: 0x00007f9a3ce61027 <-- this is a return address to the native code Console.ReadLine() which means slightly further up the stack: 0x7ffd84d06c78: 0x000000004194fdca <-- this is a return address to the caller of Console.ReadLine() (this is main) Main(), for comparison:
```cs #include main.cs ```
(gdb) x/10i 0x000000004194fdca
   0x4194fdca:  nop
   0x4194fdcb:  callq  0x41953b10  <-- so this is the last statement in main - mangler()
   0x4194fdd0:  inc    %r15d       <-- this is i++ in the loop on line 4 of main
   0x4194fdd3:  cmp    $0x3c,%r15d
   0x4194fdd7:  jl     0x4194fd78
   0x4194fdd9:  xchg   %ax,%ax
   0x4194fddb:  callq  0x4194fe26
   0x4194fde0:  movabs $0x7f9a401a4158,%rdi
   0x4194fdea:  movabs $0x4194fe1c,%r11
   0x4194fdf4:  callq  *%r11
this makes sense as a return address because we see the first thing after ReadLine(), which is mangler()! stepping back a little:
(gdb) x/30i 0x000000004194fdb0
   0x4194fdb0:  movabs $0x7f9a3ce609d0,%r11 <- pointer to native code System_Console_ReadLine()
   0x4194fdba:  callq  *%r11
   0x4194fdbd:  movabs $0x7f9a3ce60f50,%r11 <- pointer to native code System_Console_WriteLine()
   0x4194fdc7:  callq  *%r11
   0x4194fdca:  nop
   0x4194fdcb:  callq  0x41953b10           <- mangler()
   0x4194fdd0:  inc    %r15d
   0x4194fdd3:  cmp    $0x3c,%r15d
   0x4194fdd7:  jl     0x4194fd78           <- loop end
   0x4194fdd9:  xchg   %ax,%ax
   0x4194fddb:  callq  0x4194fe26           <- also mangler()??
   0x4194fde0:  movabs $0x7f9a401a4158,%rdi <- ???
   0x4194fdea:  movabs $0x4194fe1c,%r11     <- ???
   0x4194fdf4:  callq  *%r11                <- ???
   0x4194fdf7:  callq  0x4194fe26
   0x4194fdfc:  movabs $0x7f9a401a4180,%rdi
   0x4194fe06:  movabs $0x4194fe1c,%r11
   0x4194fe10:  callq  *%r11
   0x4194fe13:  mov    (%rsp),%r15
   0x4194fe17:  add    $0x18,%rsp
   0x4194fe1b:  retq                        <- main's end, whew
looking at the weird mangler() call:
(gdb) x/10i 0x4194fe26
   0x4194fe26:  callq  0x40ee3000
   0x4194fe2b:  add    $0xf0,%al
   0x4194fe2d:  lahf   
   0x4194fe2e:  lar    %ax,%ebp
   0x4194fe31:  lret   
   0x4194fe32:  xor    %ebx,-0x1(%rcx)
   0x4194fe35:  add    $0xf0,%al
   0x4194fe37:  cmp    %cl,(%rdi)
   0x4194fe39:  add    %al,%ch
   0x4194fe3b:  (bad) 
the only part of this that makes sense is the callq 0x40ee3000 - the rest is... nonsense-y. long return, really??? maybe at the call site we'll see something useful...
(gdb) x/70i 0x40ee3000
   0x40ee3000:  mov    %r11,-0xd0(%rsp)
   0x40ee3008:  pop    %r11 <------------ WHAT
   0x40ee300a:  push   %rbp
   0x40ee300b:  mov    %rsp,%rbp
   0x40ee300e:  sub    $0x160,%rsp
   0x40ee3015:  sub    $0x5,%r11
   0x40ee3019:  mov    %r11,-0x10(%rbp)
   0x40ee301d:  mov    %rax,-0x128(%rbp)
   0x40ee3024:  mov    %rcx,-0x120(%rbp)
   0x40ee302b:  mov    %rdx,-0x118(%rbp)
   0x40ee3032:  mov    %rbx,-0x110(%rbp)
   0x40ee3039:  mov    %rsp,%r11
   0x40ee303c:  add    $0x170,%r11
   0x40ee3043:  mov    %r11,-0x108(%rbp)
   0x40ee304a:  mov    0x0(%rbp),%rax
   0x40ee304e:  mov    %rax,-0x100(%rbp)
   0x40ee3055:  mov    %rsi,-0xf8(%rbp)
   0x40ee305c:  mov    %rdi,-0xf0(%rbp)
   0x40ee3063:  mov    %r8,-0xe8(%rbp)
   0x40ee306a:  mov    %r9,-0xe0(%rbp)
   0x40ee3071:  mov    %r10,-0xd8(%rbp)
   0x40ee3078:  mov    %r12,-0xc8(%rbp)
   0x40ee307f:  mov    %r13,-0xc0(%rbp)
   0x40ee3086:  mov    %r14,-0xb8(%rbp)
   0x40ee308d:  mov    %r15,-0xb0(%rbp)
   0x40ee3094:  mov    0x8(%rbp),%r11
   0x40ee3098:  mov    %r11,-0xa8(%rbp)
   0x40ee309f:  movsd  %xmm0,-0xa0(%rbp)
that pop pops the return address of this function, 0x4194fe2b, into r11, meaning we actually return to the *caller* of 0x4194fe26, back into main. so this method must use that pointer as information and probably is a 'patch-and-invoke' mechanism. the `sub $0x5, %r11` at 0x40ee3015 seals the deal, because that moves r11 back 5 bytes to point to the call here.