[PECOFF][Writer] Amend the comment about DLL linking.

llvm-svn: 185307
This commit is contained in:
Rui Ueyama 2013-07-01 07:25:30 +00:00
parent 69b6277a83
commit 8ebfad76bc
1 changed files with 25 additions and 26 deletions

View File

@ -17,7 +17,7 @@
/// purposes.
///
/// - For static linking: An archive file in this use case contains multiple
/// normal .obj files and is used for static linking. This is the same
/// regular .obj files and is used for static linking. This is the same
/// usage as .a file in Unix.
///
/// - For dynamic linking: An archive file in this use case contains pseudo
@ -36,32 +36,31 @@
/// contains a list of DLL names and list of symbols that need to be resolved by
/// the loader. Windows loader maps the executable and all the DLLs to memory,
/// resolves the symbols referencing items in DLLs, and updates the import
/// address table in memory. The import address table is an array of pointers to
/// all of the data or functions in DLL referenced by the executable. You cannot
/// access items in DLLs directly. They have to be accessed through an extra
/// level of indirection.
/// address table (IAT) in memory. The IAT is an array of pointers to all of the
/// data or functions in DLL referenced by the executable. You cannot access
/// items in DLLs directly. They have to be accessed through an extra level of
/// indirection.
///
/// So, if you want to access an item in DLL, you have to go through a
/// pointer. How do you actually do that? For each symbol in DLL, there is
/// another set of symbols with "_imp__" prefix. For example, if you have a
/// global variable "foo" in a DLL, a pointer to the variable is exported from
/// the DLL as "_imp__foo". You cannot directly use "foo" but need to go through
/// "_imp__foo", because symbol "foo" is not exported.
/// pointer. How do you actually do that? You need a symbol for a pointer in the
/// IAT. For each symbol defined in a DLL, a symbol with "__imp_" prefix is
/// exported from the DLL for an IAT entry. For example, if you have a global
/// variable "foo" in a DLL, a pointer to the variable is available as
/// "_imp__foo". The IAT is an array of _imp__ symbols.
///
/// Is this OK? That's not that complicated. Because items in a DLL are not
/// directly accessible, you need to access through a pointer, and the pointer
/// is available as a symbol with "_imp__" prefix.
/// is available as a symbol with _imp__ prefix.
///
/// Trick 1: Although you can write code with "_imp__" prefix, today's compiler
/// and linker let you write code as if there's no extra level of
/// indirection. That's why you haven't seen lots of _imp__ in your code. A
/// variable or a function declared with "dllimport" attributes is treated as an
/// item in a DLL, and the compiler automatically mangles its name and inserts
/// the extra level of indirection when accessing the item. Here are some
/// examples:
/// Note 1: Although you can write code with _imp__ prefix, today's compiler and
/// linker let you write code as if there's no extra level of indirection.
/// That's why you haven't seen lots of _imp__ in your code. A variable or a
/// function declared with "dllimport" attribute is treated as an item in a DLL,
/// and the compiler automatically mangles its name and inserts the extra level
/// of indirection when accessing the item. Here are some examples:
///
/// __declspec(dllimport) int var_in_dll;
/// var_in_dll = 3; // is equivalent to *_imp__var_in_dll = 3;
/// var_in_dll = 3; // is equivalent to *_imp__var_in_dll = 3;
///
/// __declspec(dllimport) int fn_in_dll(void);
/// fn_in_dll(); // is equivalent to (*_imp__fn_in_dll)();
@ -69,9 +68,9 @@
/// It's just the compiler rewrites code for you so that you don't need to
/// handle the indirection youself.
///
/// Trick 2: __declspec(dllimport) is mandatory for data but optional for
/// Note 2: __declspec(dllimport) is mandatory for data but optional for
/// function. For a function, the linker creates a jump table with the original
/// symbol name, so that the function is accessible without "_imp__" prefix. The
/// symbol name, so that the function is accessible without _imp__ prefix. The
/// same function in a DLL can be called through two different symbols if it's
/// not dllimport'ed.
///
@ -81,22 +80,22 @@
/// The above functions do the same thing. fn's content is a JMP instruction to
/// branch to the address pointed by _imp__fn. The latter may be a little bit
/// slower than the former because it will execute the extra JMP instruction, but
/// that's not an important point here.
/// that's usually negligible.
///
/// If a function is dllimport'ed, which is usually done in a header file,
/// mangled name will be used at compile time so the jump table will not be
/// used.
///
/// Because there's no way to hide the indirection for data access at link time,
/// data has to be accessed through dllimport'ed symbols or explicit "_imp__"
/// data has to be accessed through dllimport'ed symbols or explicit _imp__
/// prefix.
///
/// Creating Atoms for the Import Address Table
/// ===========================================
///
/// This file is to read a pseudo object file and create at most two atoms. One
/// is a shared library atom for "_imp__" symbol. The another is a defined atom
/// for the JMP instruction if the symbol is for a function.
/// The function in this file reads a pseudo object file and creates at most two
/// atoms. One is a shared library atom for _imp__ symbol. The another is a
/// defined atom for the JMP instruction if the symbol is for a function.
///
//===----------------------------------------------------------------------===//