]> granicus.if.org Git - yasm/commitdiff
Special-case _GLOBAL_OFFSET_TABLE_ in elf32/64 to generate appropriate relocs.
authorPeter Johnson <peter@tortall.net>
Tue, 21 Jul 2009 06:48:42 +0000 (06:48 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 21 Jul 2009 06:48:42 +0000 (06:48 -0000)
This was particularly noticable in GAS, but there was also a bug in NASM
output (lack of fixup within instruction in elf32).

Also:
- changed ssym lookup from a linear search to using assocdata
- added more relocation types (most not implemented)

Reported by: Mark Charney

svn path=/trunk/yasm/; revision=2206

modules/objfmts/elf/elf-machine.h
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/elf/elf-x86-amd64.c
modules/objfmts/elf/elf-x86-x86.c
modules/objfmts/elf/elf.c
modules/objfmts/elf/elf.h
modules/objfmts/elf/tests/gas32/Makefile.inc
modules/objfmts/elf/tests/gas32/elf_gas32_got.asm [new file with mode: 0644]
modules/objfmts/elf/tests/gas32/elf_gas32_got.hex [new file with mode: 0644]

index 1742e444458d26888deee6b1d70dce61d76804c1..0d8933b13f3576b5ea9e14c6bf1ab0c88bbd138c 100644 (file)
@@ -44,8 +44,7 @@
 
 #define YASM_WRITE_64Z_L(p, i)          YASM_WRITE_64C_L(p, 0, i)
 
-typedef int(*func_accepts_reloc)(size_t val, yasm_symrec *wrt,
-                                 yasm_symrec **ssyms);
+typedef int(*func_accepts_reloc)(size_t val, yasm_symrec *wrt);
 typedef void(*func_write_symtab_entry)(unsigned char *bufp,
                                        elf_symtab_entry *entry,
                                        yasm_intnum *value_intn,
@@ -57,9 +56,9 @@ typedef void(*func_write_secthead_rel)(unsigned char *bufp,
                                        elf_section_index sindex);
 
 typedef void(*func_handle_reloc_addend)(yasm_intnum *intn,
-                                        elf_reloc_entry *reloc);
-typedef unsigned int(*func_map_reloc_info_to_type)(elf_reloc_entry *reloc,
-                                                   yasm_symrec **ssyms);
+                                        elf_reloc_entry *reloc,
+                                        unsigned long offset);
+typedef unsigned int(*func_map_reloc_info_to_type)(elf_reloc_entry *reloc);
 typedef void(*func_write_reloc)(unsigned char *bufp,
                                 elf_reloc_entry *reloc,
                                 unsigned int r_type,
index 4ceccc250e3e8c8f29b7523f2d5317e82e2a3009..df5bf23330a78e7a177826b9210f4fce15226cde 100644 (file)
@@ -68,6 +68,7 @@ typedef struct {
     yasm_section *sect;
     yasm_object *object;
     unsigned long sindex;
+    yasm_symrec *GOT_sym;
 } elf_objfmt_output_info;
 
 typedef struct {
@@ -454,7 +455,7 @@ elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
     int retval;
 
     reloc = elf_reloc_entry_create(sym, NULL,
-        yasm_intnum_create_uint(bc->offset), 0, valsize);
+        yasm_intnum_create_uint(bc->offset), 0, valsize, 0);
     if (reloc == NULL) {
         yasm_error_set(YASM_ERROR_TYPE, N_("elf: invalid relocation size"));
         return 1;
@@ -463,7 +464,7 @@ elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
     elf_secthead_append_reloc(info->sect, info->shead, reloc);
 
     zero = yasm_intnum_create_uint(0);
-    elf_handle_reloc_addend(zero, reloc);
+    elf_handle_reloc_addend(zero, reloc, 0);
     retval = yasm_arch_intnum_tobytes(info->object->arch, zero, buf, destsize,
                                       valsize, 0, bc, warn);
     yasm_intnum_destroy(zero);
@@ -546,9 +547,10 @@ elf_objfmt_output_value(yasm_value *value, unsigned char *buf,
         if (value->curpos_rel)
             intn_val += offset;
 
+        /* Check for _GLOBAL_OFFSET_TABLE_ symbol reference */
         reloc = elf_reloc_entry_create(sym, wrt,
             yasm_intnum_create_uint(bc->offset + offset), value->curpos_rel,
-            valsize);
+            valsize, sym == info->GOT_sym);
         if (reloc == NULL) {
             yasm_error_set(YASM_ERROR_TYPE,
                            N_("elf: invalid relocation (WRT or size)"));
@@ -572,7 +574,7 @@ elf_objfmt_output_value(yasm_value *value, unsigned char *buf,
     }
 
     if (reloc)
-        elf_handle_reloc_addend(intn, reloc);
+        elf_handle_reloc_addend(intn, reloc, offset);
     retval = yasm_arch_intnum_tobytes(info->object->arch, intn, buf, destsize,
                                       valsize, 0, bc, warn);
     yasm_intnum_destroy(intn);
@@ -780,6 +782,7 @@ elf_objfmt_output(yasm_object *object, FILE *f, int all_syms,
     info.objfmt_elf = objfmt_elf;
     info.errwarns = errwarns;
     info.f = f;
+    info.GOT_sym = yasm_symtab_get(object->symtab, "_GLOBAL_OFFSET_TABLE_");
 
     /* Update filename strtab */
     elf_strtab_entry_set_str(objfmt_elf->file_strtab_entry,
index caa20a535c3b84a03017c62aec3a24b70fbc4e6e..bdaf82faab3d7047dca768af680cac799b0e6bec 100644 (file)
@@ -50,15 +50,14 @@ static elf_machine_ssym elf_x86_amd64_ssyms[] = {
 };
 
 static int
-elf_x86_amd64_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms)
+elf_x86_amd64_accepts_reloc(size_t val, yasm_symrec *wrt)
 {
     if (wrt) {
-        size_t i;
-        for (i=0; i<NELEMS(elf_x86_amd64_ssyms); i++) {
-            if (wrt == ssyms[i] && val == elf_x86_amd64_ssyms[i].size)
-                return 1;
-        }
-        return 0;
+        const elf_machine_ssym *ssym = (elf_machine_ssym *)
+            yasm_symrec_get_data(wrt, &elf_ssym_symrec_data);
+        if (!ssym || val != ssym->size)
+            return 0;
+        return 1;
     }
     return (val&(val-1)) ? 0 : ((val & (8|16|32|64)) != 0);
 }
@@ -131,7 +130,9 @@ elf_x86_amd64_write_secthead_rel(unsigned char *bufp,
 }
 
 static void
-elf_x86_amd64_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc)
+elf_x86_amd64_handle_reloc_addend(yasm_intnum *intn,
+                                  elf_reloc_entry *reloc,
+                                  unsigned long offset)
 {
     /* .rela: copy value out as addend, replace original with 0 */
     reloc->addend = yasm_intnum_copy(intn);
@@ -139,31 +140,30 @@ elf_x86_amd64_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc)
 }
 
 static unsigned int
-elf_x86_amd64_map_reloc_info_to_type(elf_reloc_entry *reloc,
-                                     yasm_symrec **ssyms)
+elf_x86_amd64_map_reloc_info_to_type(elf_reloc_entry *reloc)
 {
     if (reloc->wrt) {
-        size_t i;
-        for (i=0; i<NELEMS(elf_x86_amd64_ssyms); i++) {
-            if (reloc->wrt == ssyms[i] &&
-                reloc->valsize == elf_x86_amd64_ssyms[i].size) {
-                /* Force TLS type; this is required by the linker. */
-                if (elf_x86_amd64_ssyms[i].sym_rel & ELF_SSYM_THREAD_LOCAL) {
-                    elf_symtab_entry *esym;
-
-                    esym = yasm_symrec_get_data(reloc->reloc.sym,
-                                                &elf_symrec_data);
-                    if (esym)
-                        esym->type = STT_TLS;
-                }
-                /* Map PC-relative GOT to appropriate relocation */
-                if (reloc->rtype_rel &&
-                    elf_x86_amd64_ssyms[i].reloc == R_X86_64_GOT32)
-                    return (unsigned char) R_X86_64_GOTPCREL;
-                return (unsigned char) elf_x86_amd64_ssyms[i].reloc;
-            }
+        const elf_machine_ssym *ssym = (elf_machine_ssym *)
+            yasm_symrec_get_data(reloc->wrt, &elf_ssym_symrec_data);
+        if (!ssym || reloc->valsize != ssym->size)
+            yasm_internal_error(N_("Unsupported WRT"));
+
+        /* Force TLS type; this is required by the linker. */
+        if (ssym->sym_rel & ELF_SSYM_THREAD_LOCAL) {
+            elf_symtab_entry *esym;
+
+            esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data);
+            if (esym)
+                esym->type = STT_TLS;
         }
-        yasm_internal_error(N_("Unsupported WRT"));
+        /* Map PC-relative GOT to appropriate relocation */
+        if (reloc->rtype_rel && ssym->reloc == R_X86_64_GOT32)
+            return (unsigned char) R_X86_64_GOTPCREL;
+        return (unsigned char) ssym->reloc;
+    } else if (reloc->is_GOT_sym && reloc->valsize == 32) {
+        return (unsigned char) R_X86_64_GOTPC32;
+    } else if (reloc->is_GOT_sym && reloc->valsize == 64) {
+        return (unsigned char) R_X86_64_GOTPC64;
     } else if (reloc->rtype_rel) {
         switch (reloc->valsize) {
             case 8: return (unsigned char) R_X86_64_PC8;
index 07d60fd256041b86b880ee0485fd0937d605e655..5357c45a4cbf7b958dd563195bfa2f4febaea1b2 100644 (file)
@@ -58,15 +58,14 @@ static const elf_machine_ssym elf_x86_x86_ssyms[] = {
 };
 
 static int
-elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt, yasm_symrec **ssyms)
+elf_x86_x86_accepts_reloc(size_t val, yasm_symrec *wrt)
 {
     if (wrt) {
-        size_t i;
-        for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) {
-            if (wrt == ssyms[i] && val == elf_x86_x86_ssyms[i].size)
-                return 1;
-        }
-        return 0;
+        const elf_machine_ssym *ssym = (elf_machine_ssym *)
+            yasm_symrec_get_data(wrt, &elf_ssym_symrec_data);
+        if (!ssym || val != ssym->size)
+            return 0;
+        return 1;
     }
     return (val&(val-1)) ? 0 : ((val & (8|16|32)) != 0);
 }
@@ -133,33 +132,50 @@ elf_x86_x86_write_secthead_rel(unsigned char *bufp,
 }
 
 static void
-elf_x86_x86_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc)
+elf_x86_x86_handle_reloc_addend(yasm_intnum *intn,
+                                elf_reloc_entry *reloc,
+                                unsigned long offset)
 {
+    int is_GOT = reloc->is_GOT_sym;
+
+    if (reloc->wrt) {
+        const elf_machine_ssym *ssym = (elf_machine_ssym *)
+            yasm_symrec_get_data(reloc->wrt, &elf_ssym_symrec_data);
+        if (!ssym || reloc->valsize != ssym->size)
+            yasm_internal_error(N_("Unsupported WRT"));
+        if (ssym->reloc == R_386_GOTPC)
+            is_GOT = 1;
+    }
+
+    if (is_GOT && reloc->valsize == 32 && offset != 0)
+    {
+        yasm_intnum *off_intn = yasm_intnum_create_uint(offset);
+        yasm_intnum_calc(intn, YASM_EXPR_ADD, off_intn);
+        yasm_intnum_destroy(off_intn);
+    }
     return; /* .rel: Leave addend in intn */
 }
 
 static unsigned int
-elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc,
-                                   yasm_symrec **ssyms)
+elf_x86_x86_map_reloc_info_to_type(elf_reloc_entry *reloc)
 {
     if (reloc->wrt) {
-        size_t i;
-        for (i=0; i<NELEMS(elf_x86_x86_ssyms); i++) {
-            if (reloc->wrt == ssyms[i] &&
-                reloc->valsize == elf_x86_x86_ssyms[i].size) {
-                /* Force TLS type; this is required by the linker. */
-                if (elf_x86_x86_ssyms[i].sym_rel & ELF_SSYM_THREAD_LOCAL) {
-                    elf_symtab_entry *esym;
-
-                    esym = yasm_symrec_get_data(reloc->reloc.sym,
-                                                &elf_symrec_data);
-                    if (esym)
-                        esym->type = STT_TLS;
-                }
-                return (unsigned char) elf_x86_x86_ssyms[i].reloc;
-            }
+        const elf_machine_ssym *ssym = (elf_machine_ssym *)
+            yasm_symrec_get_data(reloc->wrt, &elf_ssym_symrec_data);
+        if (!ssym || reloc->valsize != ssym->size)
+            yasm_internal_error(N_("Unsupported WRT"));
+
+        /* Force TLS type; this is required by the linker. */
+        if (ssym->sym_rel & ELF_SSYM_THREAD_LOCAL) {
+            elf_symtab_entry *esym;
+
+            esym = yasm_symrec_get_data(reloc->reloc.sym, &elf_symrec_data);
+            if (esym)
+                esym->type = STT_TLS;
         }
-        yasm_internal_error(N_("Unsupported WRT"));
+        return (unsigned char) ssym->reloc;
+    } else if (reloc->is_GOT_sym && reloc->valsize == 32) {
+        return (unsigned char) R_386_GOTPC;
     } else if (reloc->rtype_rel) {
         switch (reloc->valsize) {
             case 8: return (unsigned char) R_386_PC8;
index 01c2fa5bcf80ee118a49746e27292dc12f952efa..acd83d4e9ae839c8b4c7eab7c6da81f3e75d4e6c 100644 (file)
@@ -43,12 +43,18 @@ const yasm_assoc_data_callback elf_section_data = {
 
 static void elf_symrec_data_destroy(/*@only@*/ void *d);
 static void elf_symtab_entry_print(void *data, FILE *f, int indent_level);
+static void elf_ssym_symtab_entry_print(void *data, FILE *f, int indent_level);
 
 const yasm_assoc_data_callback elf_symrec_data = {
     elf_symrec_data_destroy,
     elf_symtab_entry_print
 };
 
+const yasm_assoc_data_callback elf_ssym_symrec_data = {
+    elf_symrec_data_destroy,
+    elf_ssym_symtab_entry_print
+};
+
 extern elf_machine_handler
     elf_machine_handler_x86_x86,
     elf_machine_handler_x86_amd64;
@@ -92,6 +98,8 @@ elf_set_arch(yasm_arch *arch, yasm_symtab *symtab, int bits_pref)
             elf_ssyms[i] = yasm_symtab_define_label(symtab,
                                                     elf_march->ssyms[i].name,
                                                     NULL, 0, 0);
+            yasm_symrec_add_data(elf_ssyms[i], &elf_ssym_symrec_data,
+                                 &elf_march->ssyms[i]);
         }
     }
 
@@ -141,14 +149,15 @@ elf_reloc_entry_create(yasm_symrec *sym,
                        yasm_symrec *wrt,
                        yasm_intnum *addr,
                        int rel,
-                       size_t valsize)
+                       size_t valsize,
+                       int is_GOT_sym)
 {
     elf_reloc_entry *entry;
 
     if (!elf_march->accepts_reloc)
         yasm_internal_error(N_("Unsupported machine for ELF output"));
 
-    if (!elf_march->accepts_reloc(valsize, wrt, elf_ssyms))
+    if (!elf_march->accepts_reloc(valsize, wrt))
     {
         if (addr)
             yasm_intnum_destroy(addr);
@@ -165,6 +174,7 @@ elf_reloc_entry_create(yasm_symrec *sym,
     entry->valsize = valsize;
     entry->addend = NULL;
     entry->wrt = wrt;
+    entry->is_GOT_sym = is_GOT_sym;
 
     return entry;
 }
@@ -350,6 +360,12 @@ elf_symtab_entry_print(void *data, FILE *f, int indent_level)
     fprintf(f, "\n");
 }
 
+static void
+elf_ssym_symtab_entry_print(void *data, FILE *f, int indent_level)
+{
+    /* TODO */
+}
+
 elf_symtab_head *
 elf_symtab_create()
 {
@@ -702,11 +718,13 @@ elf_secthead_name_reloc_section(const char *basesect)
 }
 
 void
-elf_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc)
+elf_handle_reloc_addend(yasm_intnum *intn,
+                        elf_reloc_entry *reloc,
+                        unsigned long offset)
 {
     if (!elf_march->handle_reloc_addend)
         yasm_internal_error(N_("Unsupported machine for ELF output"));
-    elf_march->handle_reloc_addend(intn, reloc);
+    elf_march->handle_reloc_addend(intn, reloc, offset);
 }
 
 unsigned long
@@ -778,7 +796,7 @@ elf_secthead_write_relocs_to_file(FILE *f, yasm_section *sect,
         vis = yasm_symrec_get_visibility(reloc->reloc.sym);
         if (!elf_march->map_reloc_info_to_type)
             yasm_internal_error(N_("Unsupported arch/machine for elf output"));
-        r_type = elf_march->map_reloc_info_to_type(reloc, elf_ssyms);
+        r_type = elf_march->map_reloc_info_to_type(reloc);
 
         bufp = buf;
         if (!elf_march->write_reloc || !elf_march->reloc_entry_size)
index 1fe18bd2f13716b5c943fd85ae7d79b92aed51a9..41e9af2dab2b41994330fe2def51bd4c25dd856e 100644 (file)
@@ -330,7 +330,18 @@ typedef enum {
     R_X86_64_TLSLD = 20,        /* word32, PC-rel offset to LD GOT block */
     R_X86_64_DTPOFF32 = 21,     /* word32, offset to TLS block */
     R_X86_64_GOTTPOFF = 22,     /* word32, PC-rel offset to IE GOT entry */
-    R_X86_64_TPOFF32 = 23       /* word32, offset in initial TLS block */
+    R_X86_64_TPOFF32 = 23,      /* word32, offset in initial TLS block */
+    R_X86_64_PC64 = 24,         /* word64, PC relative */
+    R_X86_64_GOTOFF64 = 25,     /* word64, offset to GOT */
+    R_X86_64_GOTPC32 = 26,      /* word32, signed pc relative to GOT */
+    R_X86_64_GOT64 = 27,        /* word64, GOT entry offset */
+    R_X86_64_GOTPCREL64 = 28,   /* word64, signed pc relative to GOT entry */
+    R_X86_64_GOTPC64 = 29,      /* word64, signed pc relative to GOT */
+    R_X86_64_GOTPLT64 = 30,     /* like GOT64, but indicates PLT entry needed */
+    R_X86_64_PLTOFF64 = 31,     /* word64, GOT relative offset to PLT entry */
+    R_X86_64_GOTPC32_TLSDESC = 34, /* GOT offset for TLS descriptor */
+    R_X86_64_TLSDESC_CALL = 35, /* Marker for call through TLS descriptor */
+    R_X86_64_TLSDESC = 36       /* TLS descriptor */
 } elf_x86_64_relocation_type;
 
 struct elf_secthead {
@@ -377,6 +388,7 @@ struct elf_reloc_entry {
     size_t               valsize;
     yasm_intnum         *addend;
     /*@null@*/ yasm_symrec *wrt;
+    int                  is_GOT_sym;
 };
 
 STAILQ_HEAD(elf_strtab_head, elf_strtab_entry);
@@ -407,6 +419,7 @@ struct elf_symtab_entry {
 
 extern const yasm_assoc_data_callback elf_section_data;
 extern const yasm_assoc_data_callback elf_symrec_data;
+extern const yasm_assoc_data_callback elf_ssym_symrec_data;
 
 
 const elf_machine_handler *elf_set_arch(struct yasm_arch *arch,
@@ -422,7 +435,8 @@ elf_reloc_entry *elf_reloc_entry_create(yasm_symrec *sym,
                                         /*@null@*/ yasm_symrec *wrt,
                                         yasm_intnum *addr,
                                         int rel,
-                                        size_t valsize);
+                                        size_t valsize,
+                                        int is_GOT_sym);
 void elf_reloc_entry_destroy(void *entry);
 
 /* strtab functions */
@@ -491,7 +505,9 @@ struct yasm_symrec *elf_secthead_set_sym(elf_secthead *shead,
                                          struct yasm_symrec *sym);
 void elf_secthead_add_size(elf_secthead *shead, yasm_intnum *size);
 char *elf_secthead_name_reloc_section(const char *basesect);
-void elf_handle_reloc_addend(yasm_intnum *intn, elf_reloc_entry *reloc);
+void elf_handle_reloc_addend(yasm_intnum *intn,
+                             elf_reloc_entry *reloc,
+                             unsigned long offset);
 unsigned long elf_secthead_write_rel_to_file(FILE *f, elf_section_index symtab,
                                              yasm_section *sect,
                                              elf_secthead *esd,
index f9e7d11460d35daebac9acb931da1e255027f205..506e3bc54149d9c3d27e5fdf7ae047c1e854eacc 100644 (file)
@@ -5,3 +5,5 @@ TESTS += modules/objfmts/elf/tests/gas32/elf_gas32_test.sh
 EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_test.sh
 EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_ssym.asm
 EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_ssym.hex
+EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_got.asm
+EXTRA_DIST += modules/objfmts/elf/tests/gas32/elf_gas32_got.hex
diff --git a/modules/objfmts/elf/tests/gas32/elf_gas32_got.asm b/modules/objfmts/elf/tests/gas32/elf_gas32_got.asm
new file mode 100644 (file)
index 0000000..22a60a5
--- /dev/null
@@ -0,0 +1,13 @@
+.text
+
+.extern a
+
+.globl tst
+tst:
+   call L1
+L1:
+   pop %eax
+   add $_GLOBAL_OFFSET_TABLE_+(.-L1), %eax
+   mov (a@GOT)(%eax), %eax
+   movl $5, (%eax)
+   ret
diff --git a/modules/objfmts/elf/tests/gas32/elf_gas32_got.hex b/modules/objfmts/elf/tests/gas32/elf_gas32_got.hex
new file mode 100644 (file)
index 0000000..c7060e6
--- /dev/null
@@ -0,0 +1,544 @@
+7f 
+45 
+4c 
+46 
+01 
+01 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+03 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+30 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+34 
+00 
+00 
+00 
+00 
+00 
+28 
+00 
+06 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+e8 
+00 
+00 
+00 
+00 
+58 
+05 
+02 
+00 
+00 
+00 
+8b 
+80 
+00 
+00 
+00 
+00 
+c7 
+00 
+05 
+00 
+00 
+00 
+c3 
+07 
+00 
+00 
+00 
+0a 
+06 
+00 
+00 
+0d 
+00 
+00 
+00 
+03 
+04 
+00 
+00 
+00 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+72 
+65 
+6c 
+2e 
+74 
+65 
+78 
+74 
+00 
+2e 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+2e 
+73 
+79 
+6d 
+74 
+61 
+62 
+00 
+2e 
+73 
+68 
+73 
+74 
+72 
+74 
+61 
+62 
+00 
+00 
+00 
+2d 
+00 
+61 
+00 
+74 
+73 
+74 
+00 
+5f 
+47 
+4c 
+4f 
+42 
+41 
+4c 
+5f 
+4f 
+46 
+46 
+53 
+45 
+54 
+5f 
+54 
+41 
+42 
+4c 
+45 
+5f 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+f1 
+ff 
+00 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+03 
+00 
+04 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+05 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+04 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+21 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+68 
+00 
+00 
+00 
+2b 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+11 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+94 
+00 
+00 
+00 
+1f 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+19 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+b4 
+00 
+00 
+00 
+70 
+00 
+00 
+00 
+02 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+01 
+00 
+00 
+00 
+06 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+40 
+00 
+00 
+00 
+18 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+07 
+00 
+00 
+00 
+09 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+00 
+58 
+00 
+00 
+00 
+10 
+00 
+00 
+00 
+03 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+04 
+00 
+00 
+00 
+08 
+00 
+00 
+00