2021. 2. 17. 00:10ㆍ?
▶ fopen
extern _IO_FILE *_IO_new_fopen (const char*, const char*);
# define fopen(fname, mode) _IO_new_fopen (fname, mode)
fopen(fname, mode) → _IO_new_fopen(fname, mode)
▶ _IO_new_fopen
_IO_FILE *
_IO_new_fopen (const char *filename, const char *mode)
{
return __fopen_internal (filename, mode, 1);
}
_IO_new_fopen(fname, mode) → __fopen_internal(fname, mode, 1)
▶ __fopen_internal
_IO_FILE *
__fopen_internal (const char *filename, const char *mode, int is32)
{
struct locked_FILE
{
struct _IO_FILE_plus fp;
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
struct _IO_wide_data wd;
} *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
if (new_f == NULL)
return NULL;
#ifdef _IO_MTSAFE_IO
new_f->fp.file._lock = &new_f->lock;
#endif
_IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps);
_IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
_IO_new_file_init_internal (&new_f->fp);
#if !_IO_UNIFIED_JUMPTABLES
new_f->fp.vtable = NULL;
#endif
if (_IO_file_fopen ((_IO_FILE *) new_f, filename, mode, is32) != NULL)
return __fopen_maybe_mmap (&new_f->fp.file);
_IO_un_link (&new_f->fp);
free (new_f);
return NULL;
}
struct locked_FILE *new_f; // _IO_FILE_plus + lock + _IO_wide_data
new_f = malloc(sizeof(struct locked_FILE));
→ locked_FILE 구조체 malloc
_IO_no_init(&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps);
→ fp.file (_IO_FILE 구조체) 초기화, fp->_wide_data 초기화
▶ _IO_no_init
void
_IO_no_init (_IO_FILE *fp, int flags, int orientation,
struct _IO_wide_data *wd, const struct _IO_jump_t *jmp)
{
_IO_old_init (fp, flags);
fp->_mode = orientation;
if (orientation >= 0)
{
fp->_wide_data = wd;
fp->_wide_data->_IO_buf_base = NULL;
fp->_wide_data->_IO_buf_end = NULL;
fp->_wide_data->_IO_read_base = NULL;
fp->_wide_data->_IO_read_ptr = NULL;
fp->_wide_data->_IO_read_end = NULL;
fp->_wide_data->_IO_write_base = NULL;
fp->_wide_data->_IO_write_ptr = NULL;
fp->_wide_data->_IO_write_end = NULL;
fp->_wide_data->_IO_save_base = NULL;
fp->_wide_data->_IO_backup_base = NULL;
fp->_wide_data->_IO_save_end = NULL;
fp->_wide_data->_wide_vtable = jmp;
}
else
/* Cause predictable crash when a wide function is called on a byte
stream. */
fp->_wide_data = (struct _IO_wide_data *) -1L;
fp->_freeres_list = NULL;
}
fp->_wide_data 초기화
fp->_mode = orientation; // 0
fp->_wide_data = wd; // &new_f->wd
fp->_wide_data->_wide_vtable = jmp; // &_IO_wfile_jumps
▶ _IO_old_init
void
_IO_old_init (_IO_FILE *fp, int flags)
{
fp->_flags = _IO_MAGIC|flags;
fp->_flags2 = 0;
if (stdio_needs_locking)
fp->_flags2 |= _IO_FLAGS2_NEED_LOCK;
fp->_IO_buf_base = NULL;
fp->_IO_buf_end = NULL;
fp->_IO_read_base = NULL;
fp->_IO_read_ptr = NULL;
fp->_IO_read_end = NULL;
fp->_IO_write_base = NULL;
fp->_IO_write_ptr = NULL;
fp->_IO_write_end = NULL;
fp->_chain = NULL; /* Not necessary. */
fp->_IO_save_base = NULL;
fp->_IO_backup_base = NULL;
fp->_IO_save_end = NULL;
fp->_markers = NULL;
fp->_cur_column = 0;
#if _IO_JUMPS_OFFSET
fp->_vtable_offset = 0;
#endif
#ifdef _IO_MTSAFE_IO
if (fp->_lock != NULL)
_IO_lock_init (*fp->_lock);
#endif
}
fp 초기화
fp->_flags 설정 // 0xfbad0000
fp-> lock ?
[-------------------------------------code-------------------------------------]
0x7ffff7e46ad3 <_IO_new_fopen+67>: mov rdi,rbx
0x7ffff7e46ad6 <_IO_new_fopen+70>: mov r12,rbx
0x7ffff7e46ad9 <_IO_new_fopen+73>: lea r8,[rip+0x167480] # 0x7ffff7fadf60 <_IO_wfile_jumps>
=> 0x7ffff7e46ae0 <_IO_new_fopen+80>: call 0x7ffff7e56920 <_IO_no_init>
0x7ffff7e46ae5 <_IO_new_fopen+85>: lea rax,[rip+0x1679b4] # 0x7ffff7fae4a0 <_IO_file_jumps>
0x7ffff7e46aec <_IO_new_fopen+92>: mov rdi,rbx
0x7ffff7e46aef <_IO_new_fopen+95>: mov QWORD PTR [rbx+0xd8],rax
0x7ffff7e46af6 <_IO_new_fopen+102>: call 0x7ffff7e53ef0 <_IO_new_file_init_internal>
Guessed arguments:
arg[0]: 0x4052a0 --> 0x0 // &new_f->fp.file
arg[1]: 0x0
arg[2]: 0x0
arg[3]: 0x405390 --> 0x0 // &new_f->wd
arg[4]: 0x7ffff7fadf60 --> 0x0 // &_IO_wfile_jumps
_IO_no_init 후 상황
0x4052a0: 0x00000000fbad0000 0x0000000000000000
0x4052b0: 0x0000000000000000 0x0000000000000000
0x4052c0: 0x0000000000000000 0x0000000000000000
0x4052d0: 0x0000000000000000 0x0000000000000000
0x4052e0: 0x0000000000000000 0x0000000000000000
0x4052f0: 0x0000000000000000 0x0000000000000000
0x405300: 0x0000000000000000 0x0000000000000000
0x405310: 0x0000000000000000 0x0000000000000000
0x405320: 0x0000000000000000 0x0000000000405380
0x405330: 0x0000000000000000 0x0000000000000000
0x405340: 0x0000000000405390 0x0000000000000000
0x405350: 0x0000000000000000 0x0000000000000000
0x405360: 0x0000000000000000 0x0000000000000000
0x405370: 0x0000000000000000 0x0000000000000000
0x405380: 0x0000000000000000 0x0000000000000000
0x405390: 0x0000000000000000 0x0000000000000000
0x4053a0: 0x0000000000000000 0x0000000000000000
0x4053b0: 0x0000000000000000 0x0000000000000000
0x4053c0: 0x0000000000000000 0x0000000000000000
0x4053d0: 0x0000000000000000 0x0000000000000000
0x4053e0: 0x0000000000000000 0x0000000000000000
0x4053f0: 0x0000000000000000 0x0000000000000000
0x405400: 0x0000000000000000 0x0000000000000000
0x405410: 0x0000000000000000 0x0000000000000000
0x405420: 0x0000000000000000 0x0000000000000000
0x405430: 0x0000000000000000 0x0000000000000000
0x405440: 0x0000000000000000 0x0000000000000000
0x405450: 0x0000000000000000 0x0000000000000000
0x405460: 0x0000000000000000 0x0000000000000000
0x405470: 0x00007ffff7fadf60 0x0000000000020b91
gdb-peda$ x/x 0x00007ffff7fadf60
0x7ffff7fadf60 <_IO_wfile_jumps>: 0x0000000000000000
_flags = 0xfbad0000
_lock = fp+0xe0
_wide_data = fp+0xf0 (_IO_wide_data 시작 주소)
fp->_wide_data->_wide_vtable = _IO_wfile_jumps
gdb-peda$ p *(struct _IO_FILE_plus *)0x4052a0
$2 = {
file = {
_flags = 0xfbad0000,
_IO_read_ptr = 0x0,
_IO_read_end = 0x0,
_IO_read_base = 0x0,
_IO_write_base = 0x0,
_IO_write_ptr = 0x0,
_IO_write_end = 0x0,
_IO_buf_base = 0x0,
_IO_buf_end = 0x0,
_IO_save_base = 0x0,
_IO_backup_base = 0x0,
_IO_save_end = 0x0,
_markers = 0x0,
_chain = 0x0,
_fileno = 0x0,
_flags2 = 0x0,
_old_offset = 0x0,
_cur_column = 0x0,
_vtable_offset = 0x0,
_shortbuf = "",
_lock = 0x405380,
_offset = 0x0,
_codecvt = 0x0,
_wide_data = 0x405390,
_freeres_list = 0x0,
_freeres_buf = 0x0,
__pad5 = 0x0,
_mode = 0x0,
_unused2 = '\000' <repeats 19 times>
},
vtable = 0x0
}
이게되네
_IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
#define _IO_JUMPS(THIS) (THIS)->vtable
fp->vtable = _IO_file_jumps
_IO_new_file_init_internal (&new_f->fp);
void
_IO_new_file_init_internal (struct _IO_FILE_plus *fp)
{
/* POSIX.1 allows another file handle to be used to change the position
of our file descriptor. Hence we actually don't know the actual
position before we do the first fseek (and until a following fflush). */
fp->file._offset = _IO_pos_BAD;
fp->file._IO_file_flags |= CLOSED_FILEBUF_FLAGS;
_IO_link_in (fp);
fp->file._fileno = -1;
}
gdb-peda$ pd _IO_new_file_init_internal
Dump of assembler code for function _IO_new_file_init_internal:
0x00007ffff7e53ef0 <+0>: endbr64
0x00007ffff7e53ef4 <+4>: or DWORD PTR [rdi],0x240c
0x00007ffff7e53efa <+10>: push rbx
0x00007ffff7e53efb <+11>: mov rbx,rdi
0x00007ffff7e53efe <+14>: mov QWORD PTR [rdi+0x90],0xffffffffffffffff
=> 0x00007ffff7e53f09 <+25>: call 0x7ffff7e55560 <__GI__IO_link_in>
0x00007ffff7e53f0e <+30>: mov DWORD PTR [rbx+0x70],0xffffffff
0x00007ffff7e53f15 <+37>: pop rbx
0x00007ffff7e53f16 <+38>: ret
_offset = 0xffffffffffffffff
_flags |= 0x240c
▶ _IO_link_in
void
_IO_link_in (struct _IO_FILE_plus *fp)
{
if ((fp->file._flags & _IO_LINKED) == 0)
{
fp->file._flags |= _IO_LINKED;
#ifdef _IO_MTSAFE_IO
_IO_cleanup_region_start_noarg (flush_cleanup);
_IO_lock_lock (list_all_lock);
run_fp = (_IO_FILE *) fp;
_IO_flockfile ((_IO_FILE *) fp);
#endif
fp->file._chain = (_IO_FILE *) _IO_list_all;
_IO_list_all = fp;
#ifdef _IO_MTSAFE_IO
_IO_funlockfile ((_IO_FILE *) fp);
run_fp = NULL;
_IO_lock_unlock (list_all_lock);
_IO_cleanup_region_end (0);
#endif
}
}
if ((fp->file._flags & _IO_LINKED) == 0)
#define _IO_LINKED 0x80 /* Set if linked (using _chain) to streambuf::_list_all.*/
flag & 0x80 == 0 이 아니면 그냥 ret
#ifdef _IO_MTSAFE_IO
_IO_cleanup_region_start_noarg (flush_cleanup);
_IO_lock_lock (list_all_lock);
run_fp = (_IO_FILE *) fp;
_IO_flockfile ((_IO_FILE *) fp);
→ ?? new_f lock이 설정되는 것 같다
#ifdef _IO_MTSAFE_IO
_IO_funlockfile ((_IO_FILE *) fp);
run_fp = NULL;
_IO_lock_unlock (list_all_lock);
_IO_cleanup_region_end (0);
lock 영역을 썼다가 뒤에서 다시 초기화함
fp->file._flags |= _IO_LINKED; // _IO_LINKED 설정
fp->file._chain = (_IO_FILE *) _IO_list_all; // single linked list로 관리
gdb-peda$ p *(struct _IO_FILE_plus *)0x4052a0
$57 = {
file = {
...
_chain = 0x7ffff7fad5c0 <_IO_2_1_stderr_>,
...
gdb-peda$ p *(struct _IO_FILE_plus *)0x7ffff7fad5c0 // stderr
$58 = {
file = {
...
_chain = 0x7ffff7fad6a0 <_IO_2_1_stdout_>,
...
gdb-peda$ p *(struct _IO_FILE_plus *)0x7ffff7fad6a0 // stdout
$59 = {
file = {
...
_chain = 0x7ffff7fac980 <_IO_2_1_stdin_>,
...
gdb-peda$ p *(struct _IO_FILE_plus *)0x7ffff7fac980 //stdin
$60 = {
file = {
...
_chain = 0x0,
...
FILE 구조체들을 _chain을 이용해서 single linked list로 관리한다
_IO_new_file_init_internal (&new_f->fp) 실행 후
_flags = 0xfbad248c
_chain = stderr
_offset = 0xffffffffffffffff
if (_IO_file_fopen ((_IO_FILE *) new_f, filename, mode, is32) != NULL)
[-------------------------------------code-------------------------------------]
0x7ffff7e46b00 <_IO_new_fopen+112>: mov rdx,r13
0x7ffff7e46b03 <_IO_new_fopen+115>: mov rsi,rbp
0x7ffff7e46b06 <_IO_new_fopen+118>: mov rdi,rbx
=> 0x7ffff7e46b09 <_IO_new_fopen+121>: call 0x7ffff7e54260 <_IO_new_file_fopen>
0x7ffff7e46b0e <_IO_new_fopen+126>: test rax,rax
0x7ffff7e46b11 <_IO_new_fopen+129>: je 0x7ffff7e46b60 <_IO_new_fopen+208>
0x7ffff7e46b13 <_IO_new_fopen+131>: test BYTE PTR [rbx+0x74],0x1
0x7ffff7e46b17 <_IO_new_fopen+135>: je 0x7ffff7e46b4d <_IO_new_fopen+189>
Guessed arguments:
arg[0]: 0x4052a0 --> 0xfbad248c
arg[1]: filename
arg[2]: mode
arg[3]: 0x1 (?)
is32가 뭔지 모르겠는데 그냥 mov ecx,0x1로 1을 넣는다.
코드엔 _IO_file_fopen이라고 써있는데 _IO_new_file_fopen 함수 실행함
▶ _IO_new_file_fopen
_IO_FILE *
_IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
int is32not64)
{
int oflags = 0, omode;
int read_write;
int oprot = 0666;
int i;
_IO_FILE *result;
const char *cs;
const char *last_recognized;
if (_IO_file_is_open (fp))
return 0;
switch (*mode)
{
case 'r':
omode = O_RDONLY;
read_write = _IO_NO_WRITES;
break;
case 'w':
omode = O_WRONLY;
oflags = O_CREAT|O_TRUNC;
read_write = _IO_NO_READS;
break;
case 'a':
omode = O_WRONLY;
oflags = O_CREAT|O_APPEND;
read_write = _IO_NO_READS|_IO_IS_APPENDING;
break;
default:
__set_errno (EINVAL);
return NULL;
}
last_recognized = mode;
for (i = 1; i < 7; ++i)
{
switch (*++mode)
{
case '\0':
break;
case '+':
omode = O_RDWR;
read_write &= _IO_IS_APPENDING;
last_recognized = mode;
continue;
case 'x':
oflags |= O_EXCL;
last_recognized = mode;
continue;
case 'b':
last_recognized = mode;
continue;
case 'm':
fp->_flags2 |= _IO_FLAGS2_MMAP;
continue;
case 'c':
fp->_flags2 |= _IO_FLAGS2_NOTCANCEL;
continue;
case 'e':
oflags |= O_CLOEXEC;
fp->_flags2 |= _IO_FLAGS2_CLOEXEC;
continue;
default:
/* Ignore. */
continue;
}
break;
}
result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write,
is32not64);
if (result != NULL)
{
/* Test whether the mode string specifies the conversion. */
cs = strstr (last_recognized + 1, ",ccs=");
if (cs != NULL)
{
/* Yep. Load the appropriate conversions and set the orientation
to wide. */
struct gconv_fcts fcts;
struct _IO_codecvt *cc;
char *endp = __strchrnul (cs + 5, ',');
char *ccs = malloc (endp - (cs + 5) + 3);
if (ccs == NULL)
{
int malloc_err = errno; /* Whatever malloc failed with. */
(void) _IO_file_close_it (fp);
__set_errno (malloc_err);
return NULL;
}
*((char *) __mempcpy (ccs, cs + 5, endp - (cs + 5))) = '\0';
strip (ccs, ccs);
if (__wcsmbs_named_conv (&fcts, ccs[2] == '\0'
? upstr (ccs, cs + 5) : ccs) != 0)
{
/* Something went wrong, we cannot load the conversion modules.
This means we cannot proceed since the user explicitly asked
for these. */
(void) _IO_file_close_it (fp);
free (ccs);
__set_errno (EINVAL);
return NULL;
}
free (ccs);
assert (fcts.towc_nsteps == 1);
assert (fcts.tomb_nsteps == 1);
fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
/* Clear the state. We start all over again. */
memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
cc = fp->_codecvt = &fp->_wide_data->_codecvt;
/* The functions are always the same. */
*cc = __libio_codecvt;
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
cc->__cd_in.__cd.__steps = fcts.towc;
cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
cc->__cd_in.__cd.__data[0].__internal_use = 1;
cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
cc->__cd_out.__cd.__steps = fcts.tomb;
cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
cc->__cd_out.__cd.__data[0].__internal_use = 1;
cc->__cd_out.__cd.__data[0].__flags
= __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.__cd.__data[0].__statep =
&result->_wide_data->_IO_state;
/* From now on use the wide character callback functions. */
_IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
/* Set the mode now. */
result->_mode = 1;
}
}
return result;
}
if (_IO_file_is_open (fp))
return 0;
#define _IO_file_is_open(__fp) ((__fp)->_fileno != -1)
fp->_fileno가 -1이 아니면 return 0
switch case로 mode에 따라 oflags, omode를 설정
result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write, is32not64);
▶ _IO_file_open
_IO_FILE *
_IO_file_open (_IO_FILE *fp, const char *filename, int posix_mode, int prot,
int read_write, int is32not64)
{
int fdesc;
if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL))
fdesc = __open_nocancel (filename,
posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
else
fdesc = __open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
if (fdesc < 0)
return NULL;
fp->_fileno = fdesc;
_IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
/* For append mode, send the file offset to the end of the file. Don't
update the offset cache though, since the file handle is not active. */
if ((read_write & (_IO_IS_APPENDING | _IO_NO_READS))
== (_IO_IS_APPENDING | _IO_NO_READS))
{
_IO_off64_t new_pos = _IO_SYSSEEK (fp, 0, _IO_seek_end);
if (new_pos == _IO_pos_BAD && errno != ESPIPE)
{
__close_nocancel (fdesc);
return NULL;
}
}
_IO_link_in ((struct _IO_FILE_plus *) fp);
return fp;
}
if (__glibc_unlikely (fp->_flags2 & _IO_FLAGS2_NOTCANCEL))
fdesc = __open_nocancel (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
else
fdesc = __open (filename, posix_mode | (is32not64 ? 0 : O_LARGEFILE), prot);
#define _IO_FLAGS2_NOTCANCEL 2
_flags2 == 0x2 면 __open_nocancel
아니면 __open으로 파일을 연다.
▶ __open
int
__libc_open64 (const char *file, int oflag, ...)
{
int mode = 0;
if (__OPEN_NEEDS_MODE (oflag))
{
va_list arg;
va_start (arg, oflag);
mode = va_arg (arg, int);
va_end (arg);
}
return SYSCALL_CANCEL (openat, AT_FDCWD, file, oflag | EXTRA_OPEN_FLAGS,
mode);
}
/* Detect if open needs mode as a third argument (or for openat as a fourth
argument). */
#ifdef __O_TMPFILE
# define __OPEN_NEEDS_MODE(oflag) \
(((oflag) & O_CREAT) != 0 || ((oflag) & __O_TMPFILE) == __O_TMPFILE)
#else
# define __OPEN_NEEDS_MODE(oflag) (((oflag) & O_CREAT) != 0)
#endif
w나 a가 들어가면 oflag에 O_CREAT가 설정되어 if문이 수행된다.
__O_TMPFILE 은 잘 모르겠음
[----------------------------------registers-----------------------------------]
RAX: 0x101
...
[-------------------------------------code-------------------------------------]
0x7ffff7ed1e9c <__libc_open64+76>: mov rsi,rbp
0x7ffff7ed1e9f <__libc_open64+79>: mov edi,0xffffff9c
0x7ffff7ed1ea4 <__libc_open64+84>: mov eax,0x101
=> 0x7ffff7ed1ea9 <__libc_open64+89>: syscall
0x7ffff7ed1eab <__libc_open64+91>: cmp rax,0xfffffffffffff000
0x7ffff7ed1eb1 <__libc_open64+97>: ja 0x7ffff7ed1f48 <__libc_open64+248>
0x7ffff7ed1eb7 <__libc_open64+103>: mov rcx,QWORD PTR [rsp+0x28]
0x7ffff7ed1ebc <__libc_open64+108>: xor rcx,QWORD PTR fs:0x28
Guessed arguments:
arg[0]: dirfd
arg[1]: filename
arg[2]: oflag
SYSCALL_CANCEL 부분도 잘 모르겠는데
openat(dirfd, filename, oflag)가 실행되고 파일 디스크립터가 리턴된다.
결과적으로 fdesc = openat(dirfd, filename, oflag); 이 됨
if (fdesc < 0)
return NULL;
fdesc가 0보다 작으면 return NULL
fp->_fileno = fdesc;
_IO_mask_flags (fp, read_write,_IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING);
#define _IO_mask_flags(fp, f, mask) \
((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
fp->_fileno, fp->_flags 설정
_IO_link_in ((struct _IO_FILE_plus *) fp);
return fp;
얘도 single linked list로 관리하고 fp 리턴
fp _fileno, _flags 설정됨
result = fp
result = _IO_file_open (fp, filename, omode|oflags, oprot, read_write, is32not64);
if (result != NULL)
{
...
}
return result;
}
fopen 은 유니코드 파일 스트림을 지원 합니다. 유니코드 파일을 열려면 다음과 같이 fopen 에 원하는 인코딩을 지정 하는 ccs 플래그를 전달 합니다.
FILE * fp = fopen ("newfile.txt", "rt +, ccs =encoding");
// https://docs.microsoft.com/ko-kr/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-160
다음과 같이 fopen에 인코딩이 지정된 경우를 처리하고 result(==fp)를 리턴
[----------------------------------registers-----------------------------------]
RAX: 0x4052a0 --> 0xfbad2484
...
[-------------------------------------code-------------------------------------]
0x7ffff7e46b0e <_IO_new_fopen+126>: test rax,rax
0x7ffff7e46b11 <_IO_new_fopen+129>: je 0x7ffff7e46b60 <_IO_new_fopen+208>
0x7ffff7e46b13 <_IO_new_fopen+131>: test BYTE PTR [rbx+0x74],0x1
=> 0x7ffff7e46b17 <_IO_new_fopen+135>: je 0x7ffff7e46b4d <_IO_new_fopen+189>
| 0x7ffff7e46b19 <_IO_new_fopen+137>: test BYTE PTR [rbx],0x8
| 0x7ffff7e46b1c <_IO_new_fopen+140>: je 0x7ffff7e46b4d <_IO_new_fopen+189>
| 0x7ffff7e46b1e <_IO_new_fopen+142>: mov ecx,DWORD PTR [rbx+0xc0]
| 0x7ffff7e46b24 <_IO_new_fopen+148>: lea rdx,[rip+0x1672b5] # 0x7ffff7fadde0 <_IO_wfile_jumps_maybe_mmap>
|-> 0x7ffff7e46b4d <_IO_new_fopen+189>: add rsp,0x8
0x7ffff7e46b51 <_IO_new_fopen+193>: mov rax,r12
0x7ffff7e46b54 <_IO_new_fopen+196>: pop rbx
0x7ffff7e46b55 <_IO_new_fopen+197>: pop rbp
0x00007ffff7e46b13 <+131>: test BYTE PTR [rbx+0x74],0x1
0x00007ffff7e46b17 <+135>: je 0x7ffff7e46b4d <_IO_new_fopen+189>
0x00007ffff7e46b19 <+137>: test BYTE PTR [rbx],0x8
0x00007ffff7e46b1c <+140>: je 0x7ffff7e46b4d <_IO_new_fopen+189>
0x00007ffff7e46b1e <+142>: mov ecx,DWORD PTR [rbx+0xc0]
0x00007ffff7e46b24 <+148>: lea rdx,[rip+0x1672b5] # 0x7ffff7fadde0 <_IO_wfile_jumps_maybe_mmap>
0x00007ffff7e46b2b <+155>: lea rax,[rip+0x1677ee] # 0x7ffff7fae320 <_IO_file_jumps_maybe_mmap>
0x00007ffff7e46b32 <+162>: test ecx,ecx
0x00007ffff7e46b34 <+164>: cmovg rax,rdx
0x00007ffff7e46b38 <+168>: mov QWORD PTR [rbx+0xd8],rax
0x00007ffff7e46b3f <+175>: mov rax,QWORD PTR [rbx+0xa0]
0x00007ffff7e46b46 <+182>: mov QWORD PTR [rax+0xe0],rdx
0x00007ffff7e46b4d <+189>: add rsp,0x8
0x00007ffff7e46b51 <+193>: mov rax,r12
0x00007ffff7e46b54 <+196>: pop rbx
0x00007ffff7e46b55 <+197>: pop rbp
0x00007ffff7e46b56 <+198>: pop r12
0x00007ffff7e46b58 <+200>: pop r13
0x00007ffff7e46b5a <+202>: ret
#define _IO_NO_WRITES 8 /* Writing not allowd */
...
#define _IO_FLAGS2_MMAP 1
fp->_flags2에 _IO_FLAGS2_MMAP이 설정되어있고
fp->_flags에 _IO_NO_WRITES가 설정되어있으면 _IO_new_fopen+142 부분이 실행됨
뭔지는 잘 모르겠음
'?' 카테고리의 다른 글
부동소수점 (0) | 2021.08.14 |
---|---|
docker 실행 (0) | 2021.06.23 |
apt-get update... 404 not found (0) | 2021.06.23 |
glibc 2.31 free (0) | 2021.03.01 |
glibc 2.31 malloc (0) | 2021.02.21 |