{"id":47346,"date":"2015-03-11T19:08:09","date_gmt":"2015-03-11T16:08:09","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=47346"},"modified":"2019-11-27T18:07:12","modified_gmt":"2019-11-27T15:07:12","slug":"golang-internals-part-3-the-linker-object-files-and-relocations","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/","title":{"rendered":"Golang Internals, Part 3: The Linker, Object Files, and Relocations"},"content":{"rendered":"<p><center><small>All parts: <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-1-main-concepts-and-project-structure\/\">Part 1<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-2-diving-into-the-go-compiler\/\">Part 2<\/a> | <strong>Part 3<\/strong> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\">Part 4<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-5-the-runtime-bootstrap-process\/\">Part 5<\/a> | <a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\">Part 6<\/a><\/small><\/center><\/p>\n<p>&nbsp;<\/p>\n<p>In this blog post, we will touch upon the Go linker, Go object files, and relocations. Why should we care about these things? Well, if you want to learn the internals of any large project, the first thing you need to do is split it into components or modules. Second, you need to understand what interface these modules provide to each other. In Go, these high-level modules are the compiler, linker, and runtime. The interface that the compiler provides and the linker consumes is an object file, and that\u2019s where we will start our investigation today.<\/p>\n<p>&nbsp;<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#Generating_a_Go_object_file\" >Generating a Go object file<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#Investigating_the_object_file\" >Investigating the object file<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#Understanding_relocations\" >Understanding relocations<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#How_the_linker_operates\" >How the linker operates<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#Understanding_TLS\" >Understanding TLS<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#Further_reading\" >Further reading<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Generating_a_Go_object_file\"><\/span>Generating a Go object file<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Let\u2019s do a practical experiment\u2014write a super simple program, compile it, and see which object file will be produced. In our case, the program was as follows.<\/p>\n<pre style=\"padding-left:20px;\">package main\r\n\r\nfunc main() {\r\n\tprint(1)\r\n}<\/pre>\n<p>Really straightforward, isn\u2019t it? Now we need to compile it.<\/p>\n<pre style=\"padding-left:20px;\">go tool 6g test.go<\/pre>\n<p>This command produces the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">test.6<\/code> object file. To investigate its internal structure, we are going to use the <a href=\"https:\/\/github.com\/golang\/go\/tree\/master\/src\/cmd\/internal\/goobj\" target=\"_blank\" rel=\"noopener noreferrer\">goobj<\/a> library. It is employed internally in Go source code, mainly for implementing a set of unit tests that verifies whether object files are generated correctly in different situations. For this blog post, we wrote a very simple program that prints the output generated from the googj library to the console. You can take a look at the sources of this program in this <a href=\"https:\/\/github.com\/s-matyukevich\/goobj_explorer\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repo<\/a>.<\/p>\n<p>First of all, you need to download and install the program.<\/p>\n<pre style=\"padding-left:20px;\">go get github.com\/s-matyukevich\/goobj_explorer<\/pre>\n<p>Then, execute the following command.<\/p>\n<pre style=\"padding-left:20px;\">goobj_explorer -o test.6<\/pre>\n<p>Now, you should be able to see the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goob.Package<\/code> structure in your console.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Investigating_the_object_file\"><\/span>Investigating the object file<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The most interesting part of our object file is the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Syms<\/code> array. This is actually a symbol table. Everything that you define in your program\u2014functions, global variables, types, constants, etc.\u2014is written to this table. Let\u2019s look at the entry that corresponds to the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">main<\/code> function. (Note that we have cut the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Reloc<\/code> and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Func<\/code> fields from the output for now. We will discuss them later.)<\/p>\n<pre style=\"padding-left:20px;\">&goobj.Sym{\r\n            SymID: goobj.SymID{Name:\"main.main\", Version:0},\r\n            Kind:  1,\r\n            DupOK: false,\r\n            Size:  48,\r\n            Type:  goobj.SymID{},\r\n            Data:  goobj.Data{Offset:137, Size:44},\r\n            Reloc: ...,\r\n            Func:  ...,\r\n}<\/pre>\n<p>The names of the fields in the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goobj.Sum<\/code> structure are pretty self-explanatory.<\/p>\n<style type=\"text\/css\"><!--\n.myTable { background-color: transparent; border-collapse: collapse; } .myTable th { background-color: transparent; color: black; width:20%; } .myTable td, .myTable th { padding: 5px; border: 1px solid #989898; }\n--><\/style>\n<table class=\"myTable\">\n<tbody>\n<tr>\n<th><center>Field<\/center><\/th>\n<th style=\"width: 530px;\" width=\"70%\"><center>Description<\/center><\/th>\n<\/tr>\n<tr>\n<td><strong>SumID<\/strong><\/td>\n<td>The unique symbol ID that consists of the symbol\u2019s name and version. Versions help to differentiate between symbols with identical names.<\/td>\n<\/tr>\n<tr>\n<td><strong>Kind<\/strong><\/td>\n<td>Indicates to what kind the symbol belongs (more details later).<\/td>\n<\/tr>\n<tr>\n<td><strong>DupOK<\/strong><\/td>\n<td>This field indicates whether duplicates (symbols with the same name) are allowed.<\/td>\n<\/tr>\n<tr>\n<td><strong>Size<\/strong><\/td>\n<td>The size of symbol data.<\/td>\n<\/tr>\n<tr>\n<td><strong>Type<\/strong><\/td>\n<td>A reference to another symbol that represents a symbol type, if any.<\/td>\n<\/tr>\n<tr>\n<td><strong>Data<\/strong><\/td>\n<td>Contains binary data. This field has different meanings for symbols of different kinds, e.g., assembly code for functions, raw string content for string symbols, etc.<\/td>\n<\/tr>\n<tr>\n<td><strong>Reloc<\/strong><\/td>\n<td>The list of relocations (more details will be provided later).<\/td>\n<\/tr>\n<tr>\n<td><strong>Func<\/strong><\/td>\n<td>Contains special function metadata for function symbols (see more details below).<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Now, let\u2019s look at different kinds of symbols. All possible kinds of symbols are defined as constants in the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goobj<\/code> package (you can find them in this<a href=\"https:\/\/github.com\/golang\/go\/blob\/master\/src\/cmd\/internal\/goobj\/read.go#L30\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub repository<\/a>). Below, we copied the first part of these constants.<\/p>\n<pre style=\"padding-left:20px;\">const (\r\n\t_ SymKind = iota\r\n\r\n\t\/\/ readonly, executable\r\n\tSTEXT\r\n\tSELFRXSECT\r\n\r\n\t\/\/ readonly, non-executable\r\n\tSTYPE\r\n\tSSTRING\r\n\tSGOSTRING\r\n\tSGOFUNC\r\n\tSRODATA\r\n\tSFUNCTAB\r\n\tSTYPELINK\r\n\tSSYMTAB \/\/ TODO: move to unmapped section\r\n\tSPCLNTAB\r\n\tSELFROSECT\r\n\t...<\/pre>\n<p>As we can see, the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">main.main<\/code> symbol belongs to kind 1 that corresponds to the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">STEXT<\/code> constant. <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">STEXT<\/code> is a symbol that contains executable code. Now, let\u2019s look at the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Reloc<\/code> array. It consists of the following structs.<\/p>\n<pre style=\"padding-left:20px;\">type Reloc struct {\r\n\tOffset int\r\n\tSize   int\r\n\tSym    SymID\r\n\tAdd    int\r\n\tType int\r\n}<\/pre>\n<p>Each relocation implies that the bytes situated at the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">[Offset, Offset+Size]<\/code> interval should be replaced with a specified address. This address is calculated by summing up the location of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Sym<\/code> symbol with the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">Add<\/code> number of bytes.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Understanding_relocations\"><\/span>Understanding relocations<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Now, let\u2019s use an example and see how relocations work. To do this, we need to compile our program using the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">-S<\/code> switch that will print the generated assembly code.<\/p>\n<pre style=\"padding-left:20px;\">go tool 6g -S test.go<\/pre>\n<p>Let\u2019s look through the assembler and try to find the main function.<\/p>\n<pre style=\"padding-left:20px;\">\"\".main t=1 size=48 value=0 args=0x0 locals=0x8\r\n\t0x0000 00000 (test.go:3)\tTEXT\t\"\".main+0(SB),$8-0\r\n\t0x0000 00000 (test.go:3)\tMOVQ\t(TLS),CX\r\n\t0x0009 00009 (test.go:3)\tCMPQ\tSP,16(CX)\r\n\t0x000d 00013 (test.go:3)\tJHI\t,22\r\n\t0x000f 00015 (test.go:3)\tCALL\t,runtime.morestack_noctxt(SB)\r\n\t0x0014 00020 (test.go:3)\tJMP\t,0\r\n\t0x0016 00022 (test.go:3)\tSUBQ\t$8,SP\r\n\t0x001a 00026 (test.go:3)\tFUNCDATA\t$0,gclocals\u00b73280bececceccd33cb74587feedb1f9f+0(SB)\r\n\t0x001a 00026 (test.go:3)\tFUNCDATA\t$1,gclocals\u00b73280bececceccd33cb74587feedb1f9f+0(SB)\r\n\t0x001a 00026 (test.go:4)\tMOVQ\t$1,(SP)\r\n\t0x0022 00034 (test.go:4)\tPCDATA\t$0,$0\r\n\t0x0022 00034 (test.go:4)\tCALL\t,runtime.printint(SB)\r\n\t0x0027 00039 (test.go:5)\tADDQ\t$8,SP\r\n\t0x002b 00043 (test.go:5)\tRET\t,<\/pre>\n<p>In later blog posts, we\u2019ll have a closer look at this code and try to understand how the Go runtime works. For now, we are interested in the following line.<\/p>\n<pre style=\"padding-left:20px;\">0x0022 00034 (test.go:4)\tCALL\t,runtime.printint(SB)<\/pre>\n<p>This command is located at an offset of 0x0022 (in hex) or 00034 (decimal) within the function data. This line is actually responsible for calling the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.printint<\/code> function. The issue is that the compiler does not know the exact address of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.printint<\/code> function during compilation. This function is located in a different object file the compiler knows nothing about. In such cases, it uses relocations. Below is the exact relocation that corresponds to this method call (we copied it from the first output of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goobj_explorer<\/code> utility).<\/p>\n<pre style=\"padding-left:20px;\">{\r\n                    Offset: 35,\r\n                    Size:   4,\r\n                    Sym:    goobj.SymID{Name:\"runtime.printint\", Version:0},\r\n                    Add:    0,\r\n                    Type:   3,\r\n                },<\/pre>\n<p>This relocation tells the linker that, starting from an offset of 35 bytes, it needs to replace 4 bytes of data with the address of the starting point of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">runtime.printint<\/code> symbol. However, an offset of 35 bytes from the main function data is actually an argument of the call instruction that we have previously seen. (The instruction starts from an offset of 34 bytes. One byte corresponds to call instruction code and four bytes\u2014to the address of this instruction.)<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"How_the_linker_operates\"><\/span>How the linker operates<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Now that we understand this, we can figure out how the linker works. The following schema is very simplified, but it reflects the main idea.<\/p>\n<ul>\n<li style=\"margin-bottom: 6px;\">The linker gathers all the symbols from all the packages that are referenced from the main package and loads them into one big byte array (or a binary image).<\/li>\n<li style=\"margin-bottom: 6px;\">For each symbol, the linker calculates an address in this image.<\/li>\n<li style=\"margin-bottom: 6px;\">Then, it applies the relocations defined for every symbol. It is easy now, since the linker knows the exact addresses of all other symbols referenced from those relocations.<\/li>\n<li>The linker prepares all the headers necessary for the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Executable_and_Linkable_Format\" target=\"_blank\" rel=\"noopener noreferrer\">Executable and Linkable<\/a> (ELF) format on Linux or the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Portable_Executable\" target=\"_blank\" rel=\"noopener noreferrer\">Portable Executable<\/a> (PE) format on Windows. Then, it generates an executable file with the results.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Understanding_TLS\"><\/span>Understanding TLS<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>A careful reader will notice a strange relocation in the output of the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">goobj_explorer utility<\/code> for the main method. It doesn\u2019t correspond to any method call and even points to an empty symbol.<\/p>\n<pre style=\"padding-left:20px;\">{\r\n                    Offset: 5,\r\n                    Size:   4,\r\n                    Sym:    goobj.SymID{},\r\n                    Add:    0,\r\n                    Type:   9,\r\n                },<\/pre>\n<p>So, what does this relocation do? We can see that it has an offset of 5 bytes and its size is 4 bytes. At this offset, there is a command.<\/p>\n<pre style=\"padding-left:20px;\">0x0000 00000 (test.go:3)\tMOVQ\t(TLS),CX<\/pre>\n<p>It starts at an offset of 0 and occupies 9 bytes (since the next command starts at an offset of 9 bytes). We can guess that this relocation replaces the strange <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">(TLS)<\/code> statement with some address, but what is TLS and what address does it use?<\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Thread-local_storage\" target=\"_blank\" rel=\"noopener noreferrer\">TLS<\/a> is an abbreviation for Thread Local Storage. This technology is used in many programming languages. In short, it enables us to have a variable that points to different memory locations when used by different threads.<\/p>\n<p>In Go, TLS is used to store a pointer to the G structure that contains internal details of a particular Go routine (more details on this in later blog posts). So, there is a variable that\u2014when accessed from different Go routines\u2014always points to a structure with internal details of this Go routine. The location of this variable is known to the linker and this variable is exactly what was moved to the CX register in the previous command. TLS can be implemented differently for different architectures. For AMD64, TLS is implemented via the <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">FS<\/code> register, so our previous command is translated into <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">MOVQ FS<\/code>, and <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">CX<\/code>.<\/p>\n<p>To end our discussion on relocations, we are going to show you the enumerated type (<code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">enum<\/code>) that contains all the different types of relocations.<\/p>\n<pre style=\"padding-left:20px;\">\/\/ Reloc.type\r\nenum\r\n{\r\n\tR_ADDR = 1,\r\n\tR_SIZE,\r\n\tR_CALL, \/\/ relocation for direct PC-relative call\r\n\tR_CALLARM, \/\/ relocation for ARM direct call\r\n\tR_CALLIND, \/\/ marker for indirect call (no actual relocating necessary)\r\n\tR_CONST,\r\n\tR_PCREL,\r\n\tR_TLS,\r\n\tR_TLS_LE, \/\/ TLS local exec offset from TLS segment register\r\n\tR_TLS_IE, \/\/ TLS initial exec offset from TLS base pointer\r\n\tR_GOTOFF,\r\n\tR_PLT0,\r\n\tR_PLT1,\r\n\tR_PLT2,\r\n\tR_USEFIELD,\r\n};<\/pre>\n<p>As you can see from this enum, relocation type 3 is <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">R_CALL<\/code> and relocation type 9 is <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">R_TLS<\/code>. These <code style=\"color: #222222; background-color: #e6e6e6; padding: 1px 2px;\">enum<\/code> names perfectly explain the behaviour that we discussed previously.<\/p>\n<p>In the next post, we\u2019ll continue our discussion on object files. We will also provide more information necessary for you to move forward and understand how the Go runtime works. If you have any questions, feel free to ask them in the comments.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-1-main-concepts-and-project-structure\/\">Golang Internals, Part 1: Main Concepts and Project Structure<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\">Golang Internals, Part 3: The Linker, Object Files, and Relocations<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-4-object-files-and-function-metadata\/\">Golang Internals, Part 4: Object Files and Function Metadata<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-5-the-runtime-bootstrap-process\/\">Golang Internals, Part 5: the Runtime Bootstrap Process<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-6-bootstrapping-and-memory-allocator-initialization\/\">Golang Internals, Part 6: Bootstrapping and Memory Allocator Initialization<\/a><\/li>\n<\/ul>\n<hr \/>\n<p><center><small>This post was written by <b>Siarhei Matsiukevich<\/b> and edited by <a href=\"https:\/\/www.altoros.com\/blog\/author\/sophie.turol\/\">Sophia Turol<\/a> and <a href=\"https:\/\/www.altoros.com\/blog\/author\/alex\/\">Alex Khizhniak<\/a>.<\/small><\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6<\/p>\n<p>&nbsp;<\/p>\n<p>In this blog post, we will touch upon the Go linker, Go object files, and relocations. Why should we care about these things? Well, if you want to learn the internals of [&#8230;]<\/p>\n","protected":false},"author":94,"featured_media":47349,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[214],"tags":[895],"class_list":["post-47346","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-research-and-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Golang Internals, Part 3: The Linker, Object Files, and Relocations | Altoros<\/title>\n<meta name=\"description\" content=\"Learn how to generate a Go object file and work with relocations, as well as what TLS is and how the Go linker operates.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Golang Internals, Part 3: The Linker, Object Files, and Relocations | Altoros\" \/>\n<meta property=\"og:description\" content=\"All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 &nbsp; In this blog post, we will touch upon the Go linker, Go object files, and relocations. Why should we care about these things? Well, if you want to learn the internals of [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2015-03-11T16:08:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-11-27T15:07:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Siarhei Matsiukevich\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Siarhei Matsiukevich\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\",\"name\":\"Golang Internals, Part 3: The Linker, Object Files, and Relocations | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png\",\"datePublished\":\"2015-03-11T16:08:09+00:00\",\"dateModified\":\"2019-11-27T15:07:12+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png\",\"width\":1024,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Golang Internals, Part 3: The Linker, Object Files, and Relocations\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9\",\"name\":\"Siarhei Matsiukevich\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg\",\"caption\":\"Siarhei Matsiukevich\"},\"description\":\"Siarhei Matsiukevich is a Cloud Engineer and Go Developer at Altoros. With 6+ years in software engineering, he is an expert in cloud automation and designing architectures for complex cloud-based systems. An active member of the Go community, Siarhei is a frequent contributor to open-source projects, such as Ubuntu and Juju Charms.\",\"url\":\"https:\/\/www.altoros.com\/blog\/author\/siarhei-matsiukevich\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Golang Internals, Part 3: The Linker, Object Files, and Relocations | Altoros","description":"Learn how to generate a Go object file and work with relocations, as well as what TLS is and how the Go linker operates.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/","og_locale":"en_US","og_type":"article","og_title":"Golang Internals, Part 3: The Linker, Object Files, and Relocations | Altoros","og_description":"All parts: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 &nbsp; In this blog post, we will touch upon the Go linker, Go object files, and relocations. Why should we care about these things? Well, if you want to learn the internals of [...]","og_url":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/","og_site_name":"Altoros","article_published_time":"2015-03-11T16:08:09+00:00","article_modified_time":"2019-11-27T15:07:12+00:00","og_image":[{"width":1024,"height":768,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png","type":"image\/png"}],"author":"Siarhei Matsiukevich","twitter_misc":{"Written by":"Siarhei Matsiukevich","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/","url":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/","name":"Golang Internals, Part 3: The Linker, Object Files, and Relocations | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png","datePublished":"2015-03-11T16:08:09+00:00","dateModified":"2019-11-27T15:07:12+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2015\/03\/golang-internals-part-3-the-linker-object-files-and-relocations.png","width":1024,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/golang-internals-part-3-the-linker-object-files-and-relocations\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Golang Internals, Part 3: The Linker, Object Files, and Relocations"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/5c29ff93db657e3cf6552d5e642003d9","name":"Siarhei Matsiukevich","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2016\/06\/Sergey-Matyukevich-150x150.jpg","caption":"Siarhei Matsiukevich"},"description":"Siarhei Matsiukevich is a Cloud Engineer and Go Developer at Altoros. With 6+ years in software engineering, he is an expert in cloud automation and designing architectures for complex cloud-based systems. An active member of the Go community, Siarhei is a frequent contributor to open-source projects, such as Ubuntu and Juju Charms.","url":"https:\/\/www.altoros.com\/blog\/author\/siarhei-matsiukevich\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47346","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/94"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=47346"}],"version-history":[{"count":10,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47346\/revisions"}],"predecessor-version":[{"id":47846,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/47346\/revisions\/47846"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/47349"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=47346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=47346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=47346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}