forked from OSchip/llvm-project
[PECOFF][Writer] Amend the comment about DLL linking.
llvm-svn: 185307
This commit is contained in:
parent
69b6277a83
commit
8ebfad76bc
|
@ -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.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
|
Loading…
Reference in New Issue